• useCallBack和useMemo的用法


    https://juejin.cn/post/6844904101445124110#heading-6

    useCallback 的作用

    useCallback是用来优化性能的,

    但是,如果不了解它是怎么优化性能的,建议还是不要用了,因为,容易出现bug。

    useCallback返回一个函数,只有在依赖项变化的时候才会更新(返回一个新的函数)。

    import React, { useState, useCallback } from 'react';
    import Button from './Button';
    
    export default function App() {
      const [count1, setCount1] = useState(0);
      const [count2, setCount2] = useState(0);
      const [count3, setCount3] = useState(0);
    
      const handleClickButton1 = () => {setCount1(count1 + 1)};
    
      const handleClickButton2 = useCallback(() => {
        setCount2(count2 + 1);
      }, [count2]);
    
      return (
        <div>
          <div>
            <Button onClick={handleClickButton1}>Button1</Button>
          </div>
          <div>
            <Button onClick={handleClickButton2}>Button2</Button>
          </div>
          <div>
            <Button  onClick={() => {setCount3(count3 + 1);     }}>
              Button3
            </Button>
          </div>
        </div>
      );
    }
    
    
    链接:https://juejin.cn/post/6844904101445124110
    // Button.jsx
    import React from 'react';
    
    const Button = ({ onClickButton, children }) => {
      return (
        <>
          <button onClick={onClickButton}>{children}</button>
          <span>{Math.random()}</span>
        </>
      );
    };
    
    export default React.memo(Button);

    在案例中可以分别点击Demo中的几个按钮来查看效果:

    • 点击 Button1 的时候只会更新 Button1 和 Button3 后面的内容;
    • 点击 Button2 会将三个按钮后的内容都更新;
    • 点击 Button3 的也是只更新 Button1 和 Button3 后面的内容。

    经过useCallback优化后的 Button2 是点击自身时才会变更(更新),其他的两个只要父组件更新后都会变更(这里Button1 和 Button3 其实是一样的,无非就是函数换了个地方写)。

    注:Button组件里面的React.memo这个方法,会对props做一个浅层比较,如果props没有发生改变,则不会重新渲染此组件。没有用useCallback包括的函数,每次都会重新声明一个新的方法,新的方法尽管和旧的方法一样,但是依旧是两个不同的对象,React.memo对比后发现对象props改变,就重新渲染了。

    用useCallback包括的函数,根据依赖是否发生变化,才会决定是否返回一个新的函数,如果没有变化,就会返回上一次缓存的函数。

    const [count1, setCount1] = useState(0);
    const [count2, setCount2] = useState(0);
    
    const handleClickButton1 = () => {
      setCount1(count1 + 1)
    };
    const handleClickButton2 = useCallback(() => {
      setCount2(count2 + 1)
    }, [count2]);
    
    return (
      <>
        <button onClick={handleClickButton1}>button1</button>
        <button onClick={handleClickButton2}>button2</button
      </>
    )

    上面这种写法在当前组件重新渲染时 handleClickButton1 函数会重新渲染,handleClickButton2 useCallback 里面的函数也会重新渲染。反而加了 useCallback ,在执行的时候还多了 useCallback 中对 count2 的一个比较逻辑。

     useCallback 是要配合子组件的 shouldComponentUpdate 或者 React.memo 一起来使用的,否则就是反向优化,这就是前面说的bug。

    useMemo 的作用

    useMemo是在render期间执行的。所以不能进行一些额外的副操作,比如网络请求等。

    传递一个创建函数和依赖项,创建函数会需要返回一个值,只有在依赖项发生改变的时候,才会重新调用此函数,返回一个新的值。

    没有用useMemo

    // ...
    const [count, setCount] = useState(0);
    
    const userInfo = {
      // ...
      age: count,
      name: 'Jace'
    }
    
    return <UserCard userInfo={userInfo}>

    用了useMemo

    // ...
    const [count, setCount] = useState(0);
    
    const userInfo = useMemo(() => {
      return {
        // ...
        name: "Jace",
        age: count
      };
    }, [count]);
    
    return <UserCard userInfo={userInfo}>

    第一段没有用useMemo的代码,userInfo 每次都将是一个新的对象,无论 count 发生改变没,都会导致 UserCard 重新渲染,而下面的则会在 count 改变后才会返回新的对象。

    怎么用useMemo表示useCallback

    useCallback(fn,[m]);
    
    等价于
    
    useMemo(() => fn, [m]);

    结语

    useCallback缓存的是函数,useMemo 缓存的是函数的返回就结果。

    useCallback 是来优化子组件的,防止子组件的重复渲染。

    useMemo 可以优化当前组件也可以优化子组件,优化当前组件主要是通过 memoize 来将一些复杂的计算逻辑进行缓存。当然如果只是进行一些简单的计算也没必要使用 useMemo。

     
  • 相关阅读:
    教育单元测试mock框架优化之路(下)
    教育单元测试mock框架优化之路(中)
    教育单元测试mock框架优化之路(上)
    spring /spring boot中mock
    Multi-Projector Based Display Code ------- Home
    投影的一些链接
    香茅油:不只是驱虫剂 new
    python特定时间发送消息到微信公众号
    基金定投研究
    PE就是市盈率的缩写 PB是平均市净率的缩写
  • 原文地址:https://www.cnblogs.com/jwenming/p/14487141.html
Copyright © 2020-2023  润新知