ฉันไม่พอใจกับวิธีแก้ไขปัญหาใด ๆ ที่นำเสนอที่นี่ จริงๆแล้วมันมีวิธีง่ายๆที่สามารถทำได้โดยใช้ Javascript ล้วนๆโดยไม่ต้องอาศัยฟังก์ชั่น React อื่นนอกเหนือจากวัตถุประกอบฉากพื้นฐาน - และมันให้ประโยชน์ในการสื่อสารในทิศทางใดทิศทางหนึ่ง (parent -> child, child -> parent) คุณต้องผ่านวัตถุจากองค์ประกอบหลักไปยังองค์ประกอบลูก วัตถุนี้เป็นสิ่งที่ฉันเรียกว่า "การอ้างอิงสองทิศทาง" หรือ 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>;
}
ข้อดีอีกประการของวิธีนี้คือคุณสามารถเพิ่มฟังก์ชั่นได้มากขึ้นใน parent และ child ในขณะที่ส่งผ่านจาก parent ไปยัง child โดยใช้คุณสมบัติเดียวเท่านั้น
การปรับปรุงรหัสข้างต้นคือการไม่เพิ่มฟังก์ชั่นหลักและลูกโดยตรงไปยังวัตถุ 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 คุณจะมีการแยกที่ชัดเจนระหว่างทั้งสองและดูได้อย่างง่ายดายว่าสิ่งใดเป็นของพ่อแม่หรือลูก นอกจากนี้ยังช่วยป้องกันไม่ให้องค์ประกอบลูกจากการเขียนทับฟังก์ชั่นผู้ปกครองโดยไม่ตั้งใจถ้าฟังก์ชั่นเดียวกันปรากฏขึ้นในทั้งสอง
สิ่งสุดท้ายคือถ้าคุณสังเกตองค์ประกอบหลักสร้างวัตถุ biRef กับ var ในขณะที่องค์ประกอบลูกเข้าถึงวัตถุผ่านวัตถุประกอบฉาก มันอาจเป็นการล่อลวงที่จะไม่กำหนดวัตถุ biRef ในพาเรนต์และเข้าถึงมันจากพาเรนต์ผ่านพารามิเตอร์ props ของตัวเอง (ซึ่งอาจเป็นกรณีในลำดับชั้นขององค์ประกอบ UI) สิ่งนี้มีความเสี่ยงเพราะเด็กอาจคิดว่าเป็นหน้าที่ของผู้ปกครองที่เป็นของพ่อแม่เมื่อจริง ๆ แล้วมันอาจเป็นของปู่ย่าตายาย ไม่มีอะไรผิดปกติกับเรื่องนี้ตราบใดที่คุณตระหนักถึงมัน ยกเว้นว่าคุณมีเหตุผลในการสนับสนุนลำดับชั้นบางอย่างที่นอกเหนือจากความสัมพันธ์ของผู้ปกครอง / เด็กควรสร้าง biRef ในองค์ประกอบหลักของคุณ