全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货  >  详情

react 中 useMemo 和 useCallback的区别?

来源:千锋教育
发布人:qyf
2023-02-14

推荐

在线提问>>

  相同点: 这两个hook一般作为性能优化的时候使用,useMemo 计算结果是 return 回来的值, 主要用于 缓存计算结果的值 ,应用场景如: 需要 计算的状态 相当于vue中的计算属性, 只有依赖的值发生变化,计算属性才会重新计算

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

  import axios from 'axios';

  const Test = () => {

  const [keyword, setKeywordFn] = useState('')

  const [collegeArr, setCollegeFn] = useState([])

  const [count, setCount] = useState(0)

  useEffect(() => {

  //console.log('数据请求');

  axios.get('https://api.i-lynn.cn/college').then(res => {

  console.log('res', res);

  setCollegeFn(res.data.data.list1)

  })

  }, [])

  // 方式1: 当点击count++ 时, 因为函数组件的数据变化了,函数组件重新执行,则重新执行函数组件中的所有的 代码,那么getCollegelist 该值就会重新赋值.

  // const getCollegelist = collegeArr.filter((item) => {

  // console.log('代码执行1');

  // return item.school_name.includes(keyword)

  // })

  // console.log(getCollegelist);

  // 方式2: 当点击count++,getCollegelist的值不会重新赋值,因为只有依赖的keyword或collegeArr发生 变化, 该箭头函数才会重新执行,并赋值

  const getCollegelist = useMemo(() => collegeArr.filter((item) => {

  console.log('代码执行2');

  return item.school_name.includes(keyword)

  }), [keyword, collegeArr])

  // console.log(getCollegelist);

  return (

    <div>
            <p onClick={() => setCount(count + 1)}>count:{count}</p>
            <hr />
            <input value={keyword} onChange={(e) => {
                setKeywordFn(e.target.value)
            }} />
            <ul>
                {
                    getCollegelist.map((item) => {
                        return <li key={item.id}>{item.school_name}</li>
                    })
                }
            </ul>
        </div>
    );
}

export default Test;

  useCallback 计算结果是 函数, 主要用于 缓存函数,应用场景如: 需要缓存的函数,因为函数式组件每次任何一个 state 的变化 整个组件 都会被重新刷新,一些函数是没有必要被重新创建的,此时就应该缓存起来,提高性能,和减少资源浪费。

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

  const Test2 = () => {

  const [inpvalue, setinpvalue] = useState('');

  const [userList, setUserList] = useState(['张三', '李四']);

  const [useinfo, setUserinfo] = useState({ name: "小明", age: 10 });

  // 情况1: 当不使用useCallback情况下, 当修改useinfo对象中的年龄的时候, 函数组件重新执行, 这样导致

  // addUser 函数重新被创建赋值, 消耗浏览器性能

  // const addUser = () => {

  // console.log('执行了', inpvalue);

  // userList.push(inpvalue);

  // // console.log(userList);

  // setUserList([...userList])

  // }

  // 情况2: 当使用 useCallback 的时候, 会将当前useCallback中的参数如下的箭头函数缓存起来, 这样,

  // 不会发生当函数组件中的数据被修改时, 函数组件代码重新执行时, 里面的addUser 函数会被重新创建,

  // 默认如果依赖值为空,也就是 useCallback 中的第二个参数为空数组,则会导致永远都赋值的为初始函数,函数没有被重新创建,导致添加不了用户, 可以将数组的依赖项值赋值为输入框中的变量,这样当输入框中的值改变时,才重新创建函数赋值,优化性能

  const addUser = useCallback(() => {

  userList.push(inpvalue)

  // console.log(userList);

  setUserList([...userList])

  }, [inpvalue])

  console.log('执行了');

  return (

     <div>
            我是test2组件
            <p onClick={() => {
                setUserinfo({
                    ...useinfo,
                    age: useinfo.age + 1
                })
            }}>{useinfo.name}--{useinfo.age}</p>
            <hr />
            <p>
                <input value={inpvalue} onChange={
                    (e) => setinpvalue(e.target.value)
                } />
                <button onClick={addUser}>添加</button>
            </p>
            <hr />
            <ul>
                {
                    userList.map((item, index) => <li key={index}>{item}</li>)
                }
            </ul>

        </div>
    );
}

  export default Test2;

  总结: useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;并且这两个hooks都可以实现数据缓存,useMemo返回缓存的变量(重新计算的值),useCallback缓存的是函数。

相关文章

unity快捷键大全

unity射线检测多个物体

unity图集合并成图片

unity富文本字体大小

unity哪个版本免费

开班信息 更多>>

课程名称
全部学科
咨询

HTML5大前端

Java分布式开发

Python数据分析

Linux运维+云计算

全栈软件测试

大数据+数据智能

智能物联网+嵌入式

网络安全

全链路UI/UE设计

Unity游戏开发

新媒体短视频直播电商

影视剪辑包装

游戏原画

    在线咨询 免费试学 教程领取