设为首页收藏本站

安徽论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 26243|回复: 0

React.memo()、useCallback()、useMemo() 区别及基本使用

[复制链接]

1

主题

0

回帖

3

积分

新手上路

Rank: 1

积分
3
发表于 2021-12-1 15:06:06 | 显示全部楼层 |阅读模式
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
先来看个简单的例子
父组件 +1      );}export default Parent;父组件 +1       { setOtherCount(otherCount + 1); }}>父组件 otherCount+1      );}点击第一个按钮,依赖项变更,输出重新执行了计算,点击第二个按钮,因为更改的不是计算值的依赖项,因此不会重新计算,子组件也不会重新渲染
useCallback(fn[, DependentArray])


  • 用于需要传递给子组件的函数,减少子组件的重复渲染,参数为一个函数和可选的依赖项数组,返回出入函数的记忆版本
{    return parentCount + 1;  };    return (                 { setParentCount(parentCount + 1); }}>父组件 +1       { setOtherCount(otherCount + 1); }}>父组件 otherCount+1   
  );}export default Parent;// Child.jsximport React from 'react';function Child(props) {  const { computedValue, computedFn } = props;  console.log('------------子組件重新渲染');  return (                  父组件传入的计算结果:        {computedValue}      
      子組件   
  );}export default React.memo(Child);当点击第二个按钮时,子组件也会重新渲染
给computedFn 加上useCallBack
{    console.log(parentCount);    return parentCount + 1;  }, [parentCount]) ;// ...other codeexport default Parent;这时再点击父组件第二个按钮子组件,子组件不会重新渲染,因为useCallback 的依赖项没变更,返回的是上一次渲染的函数,因此传入子组件的props没变,组件不会重新渲染

  • 需要注意的是,被useCallback保存的函数内部作用域也不会变更,因此,当依赖项数组为空的时候,传入useCallback的函数的内部通过闭包取的组件内的变量值终不变
    {    // 依赖项为空,这里的打印值始终不变;    // 因为组件state变化时会重新渲染整个组件,而这里parentCount取的始终是第一次渲染版本的值    console.log(parentCount);     // 这里的打印值会实时更新,因为变量直接定义在组件外部,不受组件重新渲染影响    console.log(a);    return parentCount + 1;  }, []) ;  return (                 { setParentCount(parentCount + 1); a += 1; }}>父组件 +1       { setOtherCount(otherCount + 1); }}>父组件 otherCount+1   
      );}export default Parent;
  • 因为useCallback目的是减少子组件重渲染,因此需要搭配子组件的shouldComponentUpdate或 React.memo 一起使用才有优化意义
  • 以上是依赖项变更不频繁的情况,当依赖项变更频繁时,useCallback的记忆效果就不好,可以使用ref 作为依赖项解决
{    textRef.current = text; // 把它写入 ref  });  const handleSubmit = useCallback(() => {    // ref 对象在组件的整个生命周期内保持不变    // 从 ref 读取它,current的变更不会引起组件的重新渲染,而函数内部又能拿到正确的值    const currentText = textRef.current;     alert(currentText);  }, [textRef]);  return (           updateText(e.target.value)} />            );}useRef

看看官方介绍
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表