useImperativeHandle是用来**自定义父组件传过来的 ref **的钩子。 要点:

  • 一般用于子组件,需要搭配forwardRef使用。
  • 一般是父组件使用useRef创建ref,然后传入子组件。
const PageD = (props, ref) => {
  const subRef = useRef(null);
  useImperativeHandle(ref, () => {
    return {
      myFocus: () => {
        subRef.current.focus();
      },
    };
  });
 
  return (
    <div>
      <input type="text" ref={subRef} />
 
      <p>PageD</p>
    </div>
  );
};
export default forwardRef(PageD);
// ---
const PageC = (props) => {
  const ref = useRef(null);
 
  return (
    <div>
      PageC
      <button
        onClick={() => {
          ref.current.myFocus();
        }}
      >
        focus
      </button>
      <hr />
      <PageD ref={ref} />
      <hr />
    </div>
  );
};

与直接转发 ref 不同,直接转发 ref 是将 React.forwardRef 中函数上的 ref 参数直接应用在了返回元素的 ref 属性上,其实父、子组件引用的是同一个 ref 的 current 对象,官方不建议使用这样的 ref 透传,而使用 useImperativeHandle 后,可以让父、子组件分别有自己的 ref,通过 React.forwardRef 将父组件的 ref 透传过来,通过 useImperativeHandle 方法来自定义开放给父组件的 current。 useImperativeHandle 的第一个参数是定义 current 对象的 ref,第二个参数是一个函数,返回值是一个对象,即这个 ref 的 current 对象,这样可以像上面的案例一样,通过**自定义父组件的 ref **来使用子组件 ref 的某些方法。 https://blog.csdn.net/weixin_43720095/article/details/104967478

手写demo

https://stackblitz.com/edit/react-hook-demo-carnia?file=useImperativeHandle%2FPageD.tsx