• React 中的 useCallback 钩子函数


    1、useCallback 钩子函数简要说明

    useCallback 钩子函数有点像 useMemo 一样可以备份信息,而 useCallback 只是备份函数,除非某些参数发生变化,否则他不会重新运行其中的代码,

    2、useCallBack 例子

    // 父级组件
    const UseCallBackDemo: React.FC = () => {
      const [num, setNum] = useState<number>(0);
      const [dark, setDark] = useState<boolean>(false);
    
      const getList = () => {
        return [num, num + 1, num + 2];
      };
    
      const themeStyles = {
        backgroundColor: dark ? "black" : "white",
        color: dark ? "white" : "black",
      };
    
      return (
        <div style={themeStyles}>
          <input
            value={num}
            onChange={(e) => {
              setNum(+e.target.value);
            }}
          ></input>
          <button
            onClick={() => {
              setDark((prve) => (prve = !prve));
            }}
          >
            改变主题
          </button>
          <UseCallBackList lists={getList} />
        </div>
      );
    };
    
    // UseCallBackList 组件
    type params = {
      lists: Function;
    };
    
    const UseCallBackList: React.FC<params> = ({ lists }) => {
      const [list, setList] = useState<any>([]);
    
      useEffect(() => {
        console.log("params change");
        setList(lists());
      }, [lists]);
    
      return list.map((item: number, index: number) => <p key={index}>{item}</p>);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    出现的问题:运行上述代码后,当我们在输入框中输入数字后,再去查看控制台的日志我们可以看到打印出了params change的信息,这就表示UseCallBackList组件的useEffect钩子监听到了数据的改变,但是当我们点击改变主题按钮的时候,控制台也打印出了params change的信息。

    这是因为每次渲染应用程序组件时都会重新创建应用程序组件内部的 getList 函数,因此每次修改输入框中的值后都会重新创建该函数,所以当此函数传递给UseCallBackList组件时都会是新函数,这样每次点击以后都会重新触发。

    使用 useCallBack 钩子解决

    const getList = useCallback(() => {
      return [num, num + 1, num + 2];
    }, [num]);
    
    • 1
    • 2
    • 3

    这样修改后,上述的问题就会解决。但是我们发现useCallBack函数语法和useMemo函数一样,但是他们还是存在不同,useCallBack备份的是函数,而useMemo是备份函数处理后的结果,所以 useMemo 是不能传递参数的。

    就比如上述例子中我们可以在useCallBack中传入增量,而在子组件调用 getList 函数时,就可以传入变量值,具体的例子如下:

    // 父级组件
    const getList = useCallback(
      (increment: number) => {
        return [num + increment, num + 1 + increment, num + 2 + increment];
      },
      [num]
    );
    
    // UseCallBackList 组件
    useEffect(() => {
      console.log("params change");
      setList(lists(2));
    }, [lists]);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    GDI+是什么
    内存Webshell马详解
    Matlab图像处理-迭代式阈值选择法
    【附源码】计算机毕业设计JAVA计算机系教师教研科研管理系统
    设计模式学习(二十四):Spring 中使用到的设计模式
    ls 命令常用选项 以及 ls搭配通配符使用
    学完 Fluent 官方基础教程,你离一名合格Fluent 流体工程师还有多远?
    【Android】Lombok for Android Studio 离线插件
    如何使用SQL系列 之 如何在MySQL中使用索引
    苹果系统H5下拉加载事件重复触发(react hooks)
  • 原文地址:https://blog.csdn.net/qq_33003143/article/details/132793109