React hooks学习笔记(7)——useCallback&useMemo

useCallback:在组件中定义事件回调或者是某些函数处理时选择使用

useMemo(memory记忆):根据已有状态计算某些数据并且计算过程较消耗性能时选择使用

下面直接demo演示,还是components下新建一个CallbackMemoDemo.js并在App.js中将其引入:

import React from 'react';

export default function CallbackMemoDemo() {
    return <div>
        CallbackMemoDemo
    </div>
}
...
import CallbackMemoDemo from "./components/CallbackMemoDemo";

function App() {
  ...
  return (
    <div>
        ...
       <CallbackMemoDemo />
    </div>
  );
}

export default App;

选择假如有个定时器:

import React, { useEffect, useState } from 'react';

export default function CallbackMemoDemo() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        setInterval(() => {
            setCount(count => count + 1);
        }, 1000);
    },[]);
    console.log("updating...");
    const handleClick = () => console.log("CallbackMemoDemo click");
    return <div onClick={handleClick}>
        {count}
    </div>
}

可以发现每次count变化时,页面都会重新渲染,这个handleClick也会重新被定义,这样就造成不必要的开销,实际handleClick只用定义一次就行:

import React, { useCallback, useEffect, useState } from 'react';

export default function CallbackMemoDemo() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        setInterval(() => {
            setCount(count => count + 1);
        }, 1000);
    },[]);
    console.log("updating...");
    const handleClick = useCallback(() => console.log("CallbackMemoDemo click:", count), []);
    return <div onClick={handleClick}>
        {count}
    </div>
}

计时的过程中点击变动的数字,页面的count都计时到20了,而handleclick的count还是初始值0,说明只定义了一次:

现在如果有一个result需要根据count计算,假设它只根据count的变化而计算,而且计算一次比较费时:

import React, { useCallback, useEffect, useState } from 'react';

export default function CallbackMemoDemo() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        setInterval(() => {
            setCount(count => count + 1);
        }, 1000);
    },[]);
    const result = count * 100;
    const handleClick = useCallback(() => console.log("CallbackMemoDemo click:", count), []);
    return <div onClick={handleClick}>
        {count}--{result}
    </div>
}

如果这样写,混杂着其它变化更快的状态,那么result的计算次数也被带偏:

import React, { useCallback, useEffect, useState } from 'react';

export default function CallbackMemoDemo() {
    const [count, setCount] = useState(0);
    const [otherCount, setOtherCount] = useState(0);
    useEffect(() => {
        setInterval(() => {
            setCount(count => count + 1);
            console.log("count changing");
        }, 1000);
        setInterval(() => {
            setOtherCount(otherCount => otherCount + 1);
        }, 300);
    },[]);
    const result = count * 100;
    console.log("result calculating");
    const handleClick = useCallback(() => console.log("CallbackMemoDemo click:", count), []);
    return <div onClick={handleClick}>
        {otherCount}--{count}--{result}
    </div>
}

  result calculating应该和count changing五五开才对,这样被otherCount带着快速计算,如果result本身计算很费时间,那么app的性能就下降得很快,太多资源给了result重复计算。

所以这时候就用到useMemo:

import React, { useCallback, useEffect, useMemo, useState } from 'react';

export default function CallbackMemoDemo() {
    const [count, setCount] = useState(0);
    const [otherCount, setOtherCount] = useState(0);
    useEffect(() => {
        setInterval(() => {
            setCount(count => count + 1);
            console.log("count changing");
        }, 1000);
        setInterval(() => {
            setOtherCount(otherCount => otherCount + 1);
        }, 300);
    },[]);
    const result = useMemo(() => {
        console.log("result calculating");
        return count * 100;
    }, [count]);
    const handleClick = useCallback(() => console.log("CallbackMemoDemo click:", count), []);
    return <div onClick={handleClick}>
        {otherCount}--{count}--{result}
    </div>
}

现在result的计算就和count变化同步了

代码参考

小结: 1.useCallback一般用于存储函数,存储的函数函数体不发生更改(不会开辟新内存)

         2.useMemo一般用于根据依赖(第二个参数)重新计算(计算可能比较耗时,而且计算只和这个或这几个依赖有关),依赖变化定义的函数体才会计算

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值