我对这里提供的任何解决方案都不满意。实际上有一个非常简单的解决方案,可以使用纯 Javascript 完成,而不依赖于基本 props 对象以外的一些 React 功能 - 它为您提供了双向通信的好处(父 -> 子,子 -> 父)。您需要将一个对象从父组件传递给子组件。这个对象就是我所说的“双向引用”或简称 biRef。基本上,该对象包含对父级想要公开的父级方法的引用。并且子组件将方法附加到父组件可以调用的对象上。像这样的东西:
// Parent component.
function MyParentComponent(props) {
function someParentFunction() {
// The child component can call this function.
}
function onButtonClick() {
// Call the function inside the child component.
biRef.someChildFunction();
}
// Add all the functions here that the child can call.
var biRef = {
someParentFunction: someParentFunction
}
return <div>
<MyChildComponent biRef={biRef} />
<Button onClick={onButtonClick} />
</div>;
}
// Child component
function MyChildComponent(props) {
function someChildFunction() {
// The parent component can call this function.
}
function onButtonClick() {
// Call the parent function.
props.biRef.someParentFunction();
}
// Add all the child functions to props.biRef that you want the parent
// to be able to call.
props.biRef.someChildFunction = someChildFunction;
return <div>
<Button onClick={onButtonClick} />
</div>;
}
此解决方案的另一个优点是您可以在父和子中添加更多函数,同时仅使用单个属性将它们从父传递给子。
对上述代码的改进是不将父函数和子函数直接添加到 biRef 对象,而是添加到子成员。父函数应该添加到名为“parent”的成员中,而子函数应该添加到名为“child”的成员中。
// Parent component.
function MyParentComponent(props) {
function someParentFunction() {
// The child component can call this function.
}
function onButtonClick() {
// Call the function inside the child component.
biRef.child.someChildFunction();
}
// Add all the functions here that the child can call.
var biRef = {
parent: {
someParentFunction: someParentFunction
}
}
return <div>
<MyChildComponent biRef={biRef} />
<Button onClick={onButtonClick} />
</div>;
}
// Child component
function MyChildComponent(props) {
function someChildFunction() {
// The parent component can call this function.
}
function onButtonClick() {
// Call the parent function.
props.biRef.parent.someParentFunction();
}
// Add all the child functions to props.biRef that you want the parent
// to be able to call.
props.biRef {
child: {
someChildFunction: someChildFunction
}
}
return <div>
<Button onClick={onButtonClick} />
</div>;
}
通过将父函数和子函数放入 biRef 对象的单独成员中,您将清楚地分离两者并轻松查看哪些属于父函数或子函数。如果相同的函数出现在两个子组件中,它还有助于防止子组件意外覆盖父函数。
最后一件事是,如果您注意到,父组件使用 var 创建 biRef 对象,而子组件通过 props 对象访问它。在父级中不定义 biRef 对象并通过其自己的 props 参数从其父级访问它可能很诱人(在 UI 元素的层次结构中可能就是这种情况)。这是有风险的,因为孩子可能认为它正在调用的父函数属于父函数,而实际上它可能属于祖父母。只要你意识到这一点,这并没有错。除非您有理由支持父/子关系之外的某些层次结构,否则最好在您的父组件中创建 biRef。