我对这里介绍的任何解决方案都不满意。实际上,有一个非常简单的解决方案,可以使用纯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。