您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

实际上,useCallback和useMemo有什么区别?

实际上,useCallback和useMemo有什么区别?

useMemo 着重避免繁重的计算。

useCallback着重于另一件事:修复内联事件处理程序(如onClick={() => { doSomething(...); }引起PureComponent子项重新呈现)时的性能问题(因为函数表达式每次都有参照性的不同)

也就是说,useCallback它更接近useRef,而不是一种记忆计算结果的方法

查看文档,我确实同意它看起来令人困惑。

useCallback会返回一个已记忆的回调版本,仅当输入之一发生更改时才会更改。 当将回调传递给依赖于引用相等性的优化子组件以防止不必要的渲染 (例如,shouldComponentUpdate) 时,方法很有用。

假设我们有一个PureComponent基于子对象的子对象<Pure />,该子对象只有props在更改后才会重新渲染。

每次重新渲染父级时,此代码都会重新渲染子级,因为内联函数每次都在引用方面有所不同:

function Parent({ ... }) {
  const [a, setA] = useState(0);
  ... 
  return (
    ...
    <Pure onChange={() => { doSomething(a); }} />
  );
}

我们可以借助useCallback

function Parent({ ... }) {
  const [a, setA] = useState(0);
  const onPureChange = useCallback(() => {doSomething(a);}, []);
  ... 
  return (
    ...
    <Pure onChange={onPureChange} />
  );
}

但是一旦a更改,我们发现onPureChange我们创建的处理程序函数以及为我们记住的React仍然指向旧a值!我们有一个错误而不是性能问题!这是因为onPureChange使用闭包来访问a变量,该变量是在onPureChange声明时捕获的。为了解决这个问题,我们需要让React知道在哪里删除onPureChange并重新创建/记住(记忆)指向正确数据的新版本。为此,我们在useCallback的第二个参数中添加a`了一个依赖 项:

const [a, setA] = useState(0);
const onPureChange = useCallback(() => {doSomething(a);}, [a]);

现在,如果a已更改,React将重新渲染组件。在重新渲染期间,它会发现的依赖关系onPureChange有所不同,因此需要重新创建/存储新版本的回调。终于一切正常!

其他 2022/1/1 18:21:42 有511人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶