ここに提示された解決策のいずれにも満足できませんでした。基本的なpropsオブジェクト以外のいくつかのReact機能に依存せずに純粋なJavascriptを使用して実行できる非常に単純なソリューションが実際にあります。これにより、どちらの方向(親->子、子->親)にも通信できるという利点があります。親コンポーネントから子コンポーネントにオブジェクトを渡す必要があります。このオブジェクトは、私が「双方向参照」または略して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>;
}
このソリューションのもう1つの利点は、単一のプロパティのみを使用して、親と子に関数を渡しながら、親と子により多くの関数を追加できることです。
上記のコードの改善点は、親関数と子関数を直接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.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オブジェクトの別々のメンバーに配置することで、2つの関数を明確に分離し、どちらが親または子に属しているかを簡単に確認できます。また、同じ機能が両方にある場合に、子コンポーネントが誤って親機能を上書きするのを防ぐのにも役立ちます。
最後にもう1つ注意してください。親コンポーネントはvarでbiRefオブジェクトを作成しますが、子コンポーネントはpropsオブジェクトを通じてアクセスします。親でbiRefオブジェクトを定義せずに、独自のpropsパラメータを介して親からそのオブジェクトにアクセスするのは魅力的な場合があります(UI要素の階層の場合など)。子は、親で呼び出されている関数が実際には祖父母に属している可能性がある場合、親に属していると考える可能性があるため、危険です。あなたがそれに気づいている限り、これには何の問題もありません。親子関係以外の階層をサポートする理由がない限り、親コンポーネントでbiRefを作成するのが最善です。