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