使用 useImperativeHandle 后,可以让父、子组件分别有自己的 ref(以避免子会修改父的 DOM),通过 React.forwardRef 将父组件的 ref 转发(透传)过来,通过 useImperativeHandle 方法来自定义开放给父组件的 current。

    一般来说
    useImperativeHandle 是与 forwardRef 一起使用

    useImperativeHanlde(ref, ()=>{}, [])
    目的就是封装一个 ref, 给父组件来使用自己的 ref。ref 的内容由 ()=>{} 这个返回对象的回调来控制。而 [] 依赖项可以设置返回的对象 ref.current 以什么依赖发生改变。

    1. import React, {
    2. useState,
    3. useRef,
    4. useImperativeHandle,
    5. useCallback
    6. } from 'react';
    7. import ReactDOM from 'react-dom';
    8. const FancyInput = React.forwardRef((props, ref) => {
    9. const [ fresh, setFresh ] = useState(false)
    10. const attRef = useRef();
    11. useImperativeHandle(ref, () => ({
    12. attRef,
    13. fresh
    14. }), [ fresh ]);
    15. const handleClick = useCallback(() => {
    16. attRef.current++;
    17. }, []);
    18. return (
    19. <div>
    20. {attRef.current}
    21. <button onClick={handleClick}>Fancy</button>
    22. <button onClick={() => setFresh(!fresh)}>刷新</button>
    23. </div>
    24. )
    25. });
    26. const App = props => {
    27. const fancyInputRef = useRef();
    28. return (
    29. <div>
    30. <FancyInput ref={fancyInputRef} />
    31. <button
    32. onClick={() => console.log(fancyInputRef.current)}
    33. >父组件访问子组件的实例属性</button>
    34. </div>
    35. )
    36. }
    37. ReactDOM.render(<App />, root);