ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

useMemo 和 useCallback 简单理解

2021-09-06 16:00:56  阅读:217  来源: 互联网

标签:const useMemo text textRef 理解 useCallback handleSubmit


useMemo 和 useCallback 都是进行性能优化的手段。

某大佬:性能优化总是会有成本的,而且并不总是带来好处。比起花的时间和代码可读性,一点点的性能优化显得微不足道,除了性能重灾区之外,都不值得这么去搞。

useMemo 的使用

export default function WithMemo() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
    const expensive = useMemo(() => {
        console.log('compute');
        let sum = 0;
        for (let i = 0; i < count * 100; i++) {
            sum += i;
        }
        return sum;
    }, [count]);
 
    return <div>
        <h4>{count}-{expensive}</h4>
        {val}
        <div>
            <button onClick={() => setCount(count + 1)}>+c1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}
  1. useMemo 可以作为 Vue 的 computed 来使用。
  2. useMemo 主要用于性能优化,其中的计算比较复杂再使用。
  3. useMemo 具有缓存作用,这里只修改 val,useMemo 返回的 expensive 的值会直接从缓存获取。只有修改 count 的时候才会重新执行得到新的 expensive 的值。

useCallback 的使用

useCallback 和 useMemo 类似,只是缓存的是一个函数。

先来看一个错误的实例:

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

  const handleSubmit = useCallback(() => {
    console.log(text);
  }, [text]); // 每次 text 变化时 handleSubmit 都会变

  return (
    <>
      <input value={text} onChange={(e) => updateText(e.target.value)} />
      <ExpensiveTree onSubmit={handleSubmit} /> // 很重的组件,不优化会死的那种
    </>
  );
}

每次 input 输入框的改变都会导致 handleSubmit 改变,ExpensiveTree 组件就会重新渲染。

改成下面的方式:

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

  useLayoutEffect(() => {  // 类似 didUpdate
    textRef.current = text; // 将 text 写入到 ref
  });

  const handleSubmit = useCallback(() => {
    const currentText = textRef.current; // 从 ref 中读取 text
    alert(currentText);
  }, [textRef]); // handleSubmit 只会依赖 textRef 的变化。不会在 text 改变时更新

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

这里,我们修改 input 输入框会修改 textRef 的 current,但是 textRef 没有改变,所以 handleSubmit 也就不会改变。那么子组件 ExpensiveTree 也就不会接收到新的 handleSubmit,不会重新渲染了,性能得到了提升。

标签:const,useMemo,text,textRef,理解,useCallback,handleSubmit
来源: https://www.cnblogs.com/3body/p/15234104.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有