IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> React--hooks-- useMemo和useCallback -> 正文阅读

[JavaScript知识库]React--hooks-- useMemo和useCallback

前言:

在我们渲染页面时,有很多的函数和变量在没有被调用,但确触发并执行,父组件内的一部分在渲染时,子组件也会重新渲染等,这样会造成大量的内存消耗。
所以 React-hooks 为我们提供了 useMemo 和 useCallback 来让我们对此进行优化处理,减少此类消耗,提高整体性能。


一、useMemo 的使用

1.不使用useMemo时

function App() {
    const [count, setCount] = useState(1);
    const [value, setValue] = useState('');
    
    function getNum() {
        console.log("getNum");
        return count * 100
    }
    return (
        <div>
            <h4>总和:{getNum()}</h4>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <h4>Value: {value}</h4>
            <input value={value} onChange={event => setValue(event.target.value)} />
        </div>
    )
}

点击了2次 +1, 输入了 123
在这里插入图片描述
由此可见,上面这个组件,维护了两个state,可以看到 getNum 的计算只跟 count 有关,但是现在无论是 count 还是 value 变化,都会导致getNum重新计算,所以这里我们希望value修改的时候,getNum不需要再次计算,这种情况下我们可以使用useMemo。

2.使用useMemo

function App() {
    const [count, setCount] = useState(1);
    const [value, setValue] = useState('');
	// useMemo的返回值是一个值,所以可以用来缓存 计算出来的值
    const getNum = useMemo(() => { // 缓存了 getNum 这个值,如果count不改变,getNum就不会改变
        console.log("getNum");
        return count * 100
    }, [count])
    return (
        <div>
            <h4>总和:{getNum}</h4>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <h4>Value: {value}</h4>
            <input value={value} onChange={event => setValue(event.target.value)} />
        </div>
    )
}

点击了2次 +1, 输入了 123
在这里插入图片描述
可以看出,使用了useMemo之后,value的改变不会触发getNum了。

3.useMemo的参数 和 返回值

useMemo的参数和上一篇将的useEffect的参数是一样的,有两个:

1.第一个参数是 (计算)函数

内部一般都是存放 需要计算的值 的 计算逻辑(就比如上面的count,内部就进行了*100的操作)

2.第二个参数是 依赖项数组

(1)如果 不传 第二个参数,则 useEffect 每一次渲染都会执行
(2)如果 传入一个空数组 ,则 useEffect 只会执行一次
(3)如果 传入的数组中有依赖项,则依赖项的值改变了,useEffect 才会执行

对于 依赖项数组 的改变,三种情况都是和 useEffect 一样的,这里就不一 一举例了。

3.返回值是一个值

返回一个 memoized 值。在依赖参数不变的的情况返回的是上次第一次计算的值
可以用来储存内部函数计算出的值,这样每次调用时就不需要再运行内部的计算函数,以提高性能,除非依赖项的值改变了,否则不会重新计算。

二、useCallback 的使用

1.不使用useCallback 时

导致子组件也会重新渲染的原因:

父组件在重新渲染时,getNum 属性采用匿名函数赋值,导致每次的引用地址不一样,所以也触发了子组件的重新渲染**

function App() {
    const [count, setCount] = useState(1);
    const [value, setValue] = useState('');

    const getNum = () => {
        return count * 100
    }
    console.log("App render");
    return (
        <div>
            <Child getNum={getNum} />
            <button onClick={() => setCount(count + 1)}>+1</button>
            <h4>Value: {value}</h4>
            <input value={value} onChange={event => setValue(event.target.value)} />
        </div>
    )
}
// 用 memo 缓存 Child 组件,getNum不改变,Child就不渲染
const Child = React.memo(function ({ getNum }) {
    console.log("Child render");
    return <h4>总和:{getNum()}</h4>
})

点击了2次 +1, 输入了 123
在这里插入图片描述
由此可见,可以看到 子组件的重新渲染只跟 count 有关,但是现在无论是 count 还是 value 变化,都会导致子组件重新渲染,所以这里我们希望value修改的时候,子组件不要重新渲染,这种情况下我们可以使用useCallback 。

2.使用useCallback

function App() {
    const [count, setCount] = useState(1);
    const [value, setValue] = useState('');
	// useCallback的返回值是一个函数,可以缓存起来,只要依赖项的值不改变,内部储存这个函数的地址就不会变
    const getNum = useCallback(() => {
        return count * 100
    }, [count])

    console.log("App render");
    return (
        <div>
            <Child getNum={getNum} />
            <button onClick={() => setCount(count + 1)}>+1</button>
            <h4>Value: {value}</h4>
            <input value={value} onChange={event => setValue(event.target.value)} />
        </div>
    )
}
const Child = React.memo(function ({ getNum }) {
    console.log("Child render");
    return <h4>总和:{getNum()}</h4>
})

点击了2次 +1, 输入了 123
在这里插入图片描述
用了useCallback 后,子组件没有重新渲染。

3.useMemo的参数 和 返回值

useMemo的参数和上一篇将的useEffect的参数是一样的,有两个:

1.第一个参数是 内联回调函数

内部一般都是存放 需要缓存逻辑。

2.第二个参数是 依赖项数组

(1)如果 不传 第二个参数,则 useEffect 每一次渲染都会执行
(2)如果 传入一个空数组 ,则 useEffect 只会执行一次
(3)如果 传入的数组中有依赖项,则依赖项的值改变了,useEffect 才会执行

3.返回值是一个函数

返回(第一个参数)回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子组件时,它将非常有用。

三、useMemo 和 useCallback 的异同

相同点:

useMemo和useCallback接收的参数都是一样,而且都是在其依赖项发生变化后才会重新执行

不同点:

1. useMemo 的返回值是一个 值(函数运行的结果)
2. useCallback 的返回值是一个 函数

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-14 21:32:45  更:2021-11-14 21:34:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:46:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码