繁体   English   中英

使用 ref 防止来自 useCallback 的经常变化的值

[英]Use of ref to prevent often-changing value from useCallback

在 Reach Hooks 常见问题解答部分“如何从 useCallback 中读取经常变化的值?” 有一个例子:

function Form() {
  const [text, updateText] = useState('');
  const textRef = useRef();

  useEffect(() => {
    textRef.current = text; // Write it to the ref
  });

  const handleSubmit = useCallback(() => {
    const currentText = textRef.current; // Read it from the ref
    alert(currentText);
  }, [textRef]); // Don't recreate handleSubmit like [text] would do

  return (
    <>
      <input value={text} onChange={e => updateText(e.target.value)} />
      <ExpensiveTree onSubmit={handleSubmit} />
    </>
  );
}

我很困惑:

  • 每次文本更改时,useCallback 都不会更新 function,而是将此代码移动到 useEffect 中的 textRef。 但是这不一样吗,因为回调 function 没有改变,但您仍然需要 1 步来更新 useEffect 中的值?
  • 为什么 textRef 在依赖数组中? textRef 不是在渲染之间不会改变的引用吗? 我们总是收到相同的引用,所以它与输入一个空数组不一样吗?

而不是 useCallback 每次文本更改时更新 function,此代码将其移动到 useEffect 中的 textRef 但不一样,因为回调 function 不会改变,但您仍然需要 1 步来更新 useEffect 中的值?

使用useRef设置,每个渲染都会重新运行useEffecthandleSubmit保持不变。 在正常设置中,每个渲染都将重新运行useCallback并且handleSubmit将是对新 function 的新引用。 我可以明白为什么从表面上看这似乎是相同的工作量。

ref 方法的好处是基于Form的重新渲染发生的其他重新渲染。 每次text的值发生变化时,父Form会重新渲染,而子input会重新渲染,因为它将text作为 prop。 ExpensiveTree不会重新渲染,因为它的 prop handleSubmit保持相同的引用。 当然, ExpensiveTree这个名称旨在告诉我们,我们希望尽量减少该组件的重新渲染,因为它的计算成本很高。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM