React.memo、React Hooks 里 useMemo 和 useCallback 的区别及运用

useMemo

用来缓存数据,当组件内部某一部分渲染的数据(组件),需要通过计算而来,这个计算是依赖与特定的state、props数据,我们就用 useMemo 来缓存这个数据,以至于我们在修改她们没有依赖的数据源的情况下,多次调用这个计算函数,浪费计算资源。

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

function UserInfo(props) {
  const [ name, setName ] = useState('');
  const [ userData, setUserData ] = useState({
      name: '伍哥的传说',
      likes: [
        {
          id: 1,
          title: '编程'
        },
        {
          id: 2,
          title: '旅游'
        },
        {
          id: 3,
          title: '跑步'
        },
        {
          id: 4,
          title: '听歌'
        }
      ]
  });

  const getLikes = (data) => {
    console.log('渲染爱好')

    return (
      <>
        {data.map(item => {
          return <li key={item.id}>{item.id}、{item.title}</li>
        })}
      </>
    )
  }

  // BAD 
  // 不使用useMemo的情况下,修改其他属性,也会重新调用 getLikes 方法,浪费计算资源
  // const renderLikes = (data) => {
  //   return getLikes(data)
  // }

  // GOOD
  const renderLikes = useMemo(() => {
    return getLikes(userData.likes)
  }, [userData.likes])

  return (
    <div style={{padding: '20px', border: '1px solid #ccc', borderRadius: '2px', margin: '20px'}}>
      <h1>姓名:{userData.name}</h1>
      <ul>{renderLikes}</ul>
      <input type="text" onChange={(e) => setName(e.target.value)} />
      <input type="submit" onClick={() => setUserData({
        ...userData,
        name 
      })} />
    </div>
  )
}

export default UserInfo;

上面是把组件当做数据缓存起来,其实有更方便的方法只要稍加改动就可以。比如用用 React.memo LikesLi组件

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

let Likes = function(props) {
  const data = props.data;
  console.log('渲染爱好')

  return (
    <>
      {data.map(item => {
        return <li key={item.id}>{item.id}、{item.title}</li>
      })}
    </>
  )
}

Likes = React.memo(Likes)

function UserInfo(props) {
  const [ name, setName ] = useState('');
  const [ userData, setUserData ] = useState({
      name: '伍哥的传说',
      likes: [
        {
          id: 1,
          title: '编程'
        },
        {
          id: 2,
          title: '旅游'
        },
        {
          id: 3,
          title: '跑步'
        },
        {
          id: 4,
          title: '听歌'
        }
      ]
  });

  const addLikes = () => {
    setUserData({
      ...userData,
      likes: [...userData.likes, {
        id: 5,
        title: '钓鱼'
      }]
    })
  }

  return (
    <div style={{padding: '20px', border: '1px solid #ccc', borderRadius: '2px', margin: '20px'}}>
      <h1>姓名:{userData.name}</h1>
      <ul>
        <Likes data={userData.likes} />
      </ul>
      <input type="text" onChange={(e) => setName(e.target.value)} />
      <input type="submit" onClick={() => setUserData({
        ...userData,
        name 
      })} value="修改姓名" />
      <br /><br />
      <input type="button" value="添加喜好" onClick={addLikes} />
    </div>
  )
}

export default UserInfo;

useCallback

用来缓存函数,这个函数如果是由父组件传递给子组件,或者自定义hooks里面的函数【通常自定义hooks里面的函数,不会依赖于引用它的组件里面的数据】,这时候我们可以考虑缓存这个函数,好处:

1,不用每次重新声明新的函数,避免释放内存、分配内存的计算资源浪费
2,子组件不会因为这个函数的变动重新渲染。【和React.memo搭配使用】

由此可见,useCallback 主要用来缓存函数,虽然useMemo也能实现,但是callback写法直观。

缓存函数的时候,闭包变量也会被缓存,所以新手还是不推荐使用,容易出bug。每次render时定义新的函数就可以,成本很小。

缓存函数的好处是,保证这个函数的引用不变。比如说有个组件A,是Pure Component,或者被React.memo包裹,而它需要通过props传递一个函数。。如果每次render,没有用useCallback缓存函数,func都会是一个新的对象,那么Pure Component或者React.memo就没用了。这个时候useCallback作用就体现出来了,能在多次渲染期间保持引用不变(只要dependencies不变)。

更多React Hooks 特性分享推荐

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伍哥的传说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值