react hooks 里 useMemo 和 useCallback的区别

react hooks提供的两个API,用于缓存数据,优化性能。

useMemo

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

直接上代码

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

function Info(props) {
  let [personalInfo , setPersonalInfo] = useState({
    name: 'kevin kang',
    gender: 'male'
  })

  function formatGender(gender) {
    console.log('---调用了翻译性别的方法---')
    return gender === 'male' ? '男' : '女'
  }


  // BAD 
  // 不使用useMemo的情况下,修改其他属性,也会重新调用formatGender方法,浪费计算资源
  // let gender =  formatGender(personalInfo.gender)

  // GOOD
  let gender = useMemo(()=>{
    return formatGender(personalInfo.gender)
  }, 
  [personalInfo.gender])

  return (
    <>
        <div>
          姓名: {personalInfo.name} -- 性别:  { gender } <br/>
          <button onClick={ 
            ()=> { 
              setPersonalInfo({
                ...personalInfo,
                name: 'Will Kang'
              }) 
            }  
          }> 点击修改名字</button>
        </div>
    </>
  )
}

export default Info

useCallback

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

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

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

// BAD
// function ListItem(props) {
//   let addItem = props.addItem
//   useEffect(()=>{
//     console.log('子组件ListItem 加载')
//   },[])
//   useEffect(()=>{
//     console.log('子组件render')
//   })
//   return (
//     <div onClick={ addItem }> { props.children } </div>
//   )
// }

// GOOD shouldComponentUpdate
const ListItem = React.memo((props)=> {
  let addItem = props.addItem
  useEffect(()=>{
    console.log('子组件ListItem 加载')
  },[])
  useEffect(()=>{
    console.log('子组件render')
  })
  return (
    <div onClick={ addItem }> { props.children } </div>
  )
})

let count = 0
function List(props) {

  let [list, setList] = useState([])

  let [name, setName] = useState('Kevin')
  useEffect(()=>{
    setList([
      '6点起床',
      '7点上班',
      '8点早会'
    ])
  }, [])

  const addI = useCallback(()=>{
    list.push('行程 '+ count)
    setList([...list])
  }, [list])

  const modifyName = () => {
    setName('K3VIN' + (++count))
  }
  
  return (
    <>
      {
        list.map((item, index) => {

            return <ListItem key={index} addItem = { addI }> 
                    {item} 
                </ListItem>

        })
      }
      现在的名字: {name}  <button onClick={modifyName}> 点击修改名字 </button>
    </>
  )
}

export default List

使用memoAPI来缓存组件。

import React, { memo } from 'react';


const CacheComponent = memo(()=>{
	return (
		<div>
		// ... component content
		</div>
	)
})

资料:https://github.com/facebook/react/issues/15156#issuecomment-474590693

练习集合: 仓库地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值