文档中提供的示例如下:
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} />;
}
FancyInput = forwardRef(FancyInput);
据我所知,我可以通过以下方式实现同样的事情
function FancyInput(props, ref) {
const inputRef = useRef();
useEffect(() => {
if (ref) {
ref.current = {
focus: () => {
inputRef.current.focus();
}
};
}
}, [ref]);
return <input ref={inputRef} />;
}
FancyInput = forwardRef(FancyInput);
useImperativeHandle不那么冗长的可能解释对我来说似乎太微不足道了。引擎盖下有什么?是什么让它比useEffect版本更必要或更好?
TLDR;这是相同的,useImperativeHandle
只处理所有ref
情况,并确保传递的值是 ref 而不仅仅是任何值。
回答您的问题它为您处理使用 refs 时所需的一切,因此可以节省一些代码。
我正在查看钩子的源代码,看起来像在引擎盖下,useImperativeHandle
与您使用useEffect
的方法几乎相同.
你可以看看钩子,看看它们有一个HooksDispatcherOnMount,HooksDispatcherOnUpdate和HooksDispatcherOnRerender。
如果你看一下相关的函数(fooImperativeHandle
和fooEffect
(,你会发现两者都调用同一个函数(fooEffectImpl
(。
所以显然,在引擎盖下,这是一回事,但是使用useImperativeHandle
时,您不需要处理.current
的部分,它已经检查了null
值,检查它是否是一个ref
并在.current
中设置返回值,如下所示 这里.
这就是我从查看源代码中得到的,但是如果我错了,请纠正我。