如评论中所述,我的观点是,当依赖项更改过于频繁时(在useEffect
/ useCallback
dep 数组中),这个钩子在“你得到多少渲染”方面是多余的,使用普通函数是最好的选择(没有高架)。
这个钩子隐藏了使用它的组件的渲染,但渲染来自useEffect
其父级。
如果我们总结我们得到的渲染计数:
- Ref + useCallback(钩子):Render in
Component
(due to value
) + Render in hook ( useEffect
),一共2个。
- useCallback only:Render in
Component
(due to value
) + render in Counter
(change in function reference duo to value
change),一共2个。
- 正常功能:渲染输入
Component
+渲染输入Counter
:每次渲染新功能,总共2个。
但是在useEffect
or中进行浅层比较会得到额外的开销useCallback
。
实际例子:
function App() {
const [value, setValue] = useState("");
return (
<div>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
type="text"
/>
<Component value={value} />
</div>
);
}
function useLastVersion(func) {
const ref = useRef();
useEffect(() => {
ref.current = func;
console.log("useEffect called in ref+callback");
}, [func]);
return useCallback((...args) => {
return ref.current(...args);
}, []);
}
function Component({ value }) {
const f1 = useLastVersion(() => {
alert(value.length);
});
const f2 = useCallback(() => {
alert(value.length);
}, [value]);
const f3 = () => {
alert(value.length);
};
return (
<div>
Ref and useCallback:{" "}
<MemoCounter callBack={f1} msg="ref and useCallback" />
Callback only: <MemoCounter callBack={f2} msg="callback only" />
Normal: <MemoCounter callBack={f3} msg="normal" />
</div>
);
}
function Counter({ callBack, msg }) {
console.log(msg);
return <button onClick={callBack}>Click Me</button>;
}
const MemoCounter = React.memo(Counter);
作为旁注,如果目的只是找到input
最小渲染的长度,那么阅读inputRef.current.value
将是解决方案。