• 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
  • 相关阅读:
    Linux----生产者和消费者模型
    vue3+element-plus权限控制实现(el-tree父子级不关联情况处理)
    域控操作三点五:使用策略下发将域用户添加到本地管理员组
    Spring MVC请求处理流程和九大组件
    【代码精读】optee的进入和退出的方式
    [OpenJDK:环境变量配置]:填充Profile并修改默认配置
    【matplotlib 实战】--折线图
    Linux&Ubuntu安装OpenWAF
    【Oculus Interaction SDK】(七)使用射线进行交互(物体 & UI)
    Vue中如何进行多语言处理
  • 原文地址:https://blog.csdn.net/qq_33003143/article/details/132793109