React講解 - 父元件呼叫子元件內容【更新中】

specialCoder發表於2022-04-01

前言

本篇文章屬於 React通訊 > 父子通訊 > 父元件呼叫子元件 的內容。
父元件呼叫子元件的場景:

  • 子元件被多個地方使用,需要單獨封裝
  • 子元件邏輯較重,使用完全受控模式成本較高

使用父元件呼叫子元件進行邏輯呼叫有以下優勢:

  • 子元件可以封裝,進行復用。並且裡面的邏輯不受外界干擾
  • 可以把更多相關邏輯封裝在子元件裡,而不需要傳遞 props
  • 蒐集資料簡單

正文

Class Component

Hooks

使用到的hooks:useImperativeHandleuseRef

/* child子元件 */
// https://reactjs.org/docs/hooks-reference.html#useimperativehandle
import {useState, useImperativeHandle} from 'react';
...
// props子元件中需要接受ref
const ChildComp = ({cRef}) => {
    const [val, setVal] = useState();
    // 此處注意useImperativeHandle方法的的第一個引數是目標元素的ref引用
    useImperativeHandle(cRef, () => ({
        // changeVal 就是暴露給父元件的方法
        changeVal: (newVal) => {
          setVal(newVal);
        }
    }));
    ...
    return (
        <div>{val}</div>
    )
}
/* FComp 父元件 */
import {useRef} from 'react;
...
const FComp = () => {
    const childRef = useRef();
    const updateChildState = () => {
        // changeVal就是子元件暴露給父元件的方法
        childRef.current.changeVal(99);
    }
    ...
    return (
        <>
            {/* 此處注意需要將childRef通過props屬性從父元件中傳給自己 cRef={childRef} */}
            <ChildComp  cRef={childRef} />
            <button onClick={updateChildState}>觸發子元件方法</button>
        </>
    )
}
  

方法二、參考react官方文件:

import {useState, useImperativeHandle,forwardRef} from 'react';
// props子元件中需要接受ref
let ChildComp = (props,ref) => {
    // 此處注意useImperativeHandle方法的的第一個引數是目標元素的ref引用
    useImperativeHandle(ref, () => ({
        // changeVal 就是暴露給父元件的方法
        changeVal: (newVal) => {
           
        }
    }));
    return (
        <div>{val}</div>
    )
}
ChildComp = forwardRef(ChildComp)
/* FComp 父元件 */
import {useRef} from 'react';
const FComp = () => {
    const childRef = useRef();
    const updateChildState = () => {
        // changeVal就是子元件暴露給父元件的方法
        childRef.current.changeVal(99);
    }
    return (
        <>
            <ChildComp ref={childRef} />
            <button onClick={updateChildState}>觸發子元件方法</button>
        </>
    )
}

總結

demo:

  • props ref: https://codepen.io/specialCod...
  • forwardRef: https://codepen.io/specialCod...
  • common object: https://codepen.io/specialCod...
    總結:
  • 都可以實現父元件呼叫子元件方法
  • 無論是 props ref 還是 forwardRef 都是為了向子元件傳遞 ref
  • 實現需要一個 ref 物件 (為什麼是ref? 特性是?) 【其實只要是傳遞一個物件就可以,ref 應該是和元件生命週期有關係】
  • Cannot read property 'getList' of undefined ( null in ref)
  • 實現需要 useImperativeHandle 起到繫結方法到物件上的作用
  • 給ref.current賦值是個副作用,所以一般在Did函式或者事件處理函式裡給ref.current賦值;
  • 元件在解除安裝時要清理ref.current的值。
    本質上useImperativeHandle就是在幫我們做這些事情。

todo:

  • 受控通訊方式簡單介紹

相關文章