useCallback和useMemo的区别

在这里插入图片描述
useCallback的使用方式在这里就不重复描述了,
(注:可以看这篇文章:https://blog.csdn.net/rock_23/article/details/121410694)
useMemo的使用

import { useState, useMemo } from 'react'
import { Button } from 'antd'

const Home: React.FC = () => {
  const [ count, setCount ] = useState<number>(0)
  // 因为没有使用useMemo的原因,导致点击多少次按钮,就会调用多少次  
  const countToString = (() => {
    console.log('countToString:  被调用')
    return count.toString()
  })()
  const memoCountToString = useMemo(() => {
    console.log('memoCountToString:  被调用')
    return count.toString()
    // useMemo如果不设置第二参数为count的话,那么这个函数无论点击
    // 多少次,都只会打印一次,而设置了第二参数要监听的数据后,
    // 当你内容改变了,才会触发
  }, [count]) 
  return <>
    <div>
      <div>------------  分界线 useMemo  -------------</div>
      <h3>countToString: {countToString}</h3>
      <h3>memoCountToString:{memoCountToString}</h3>
      <Button onClick={() => setCount((code) => code + 1)}>usememo count</Button>
      <Button onClick={() => setCount(count + 1)}>useMemo +1</Button>
    </div>
  </>
}

export default Home

useCallback和useMemo一起使用
解决:
为了使 Button 组件不进行重复渲染,我们必须这么做

  • 必须使用 useCallback hook来包裹 onClick 函数。

  • 并且使用 useMemo hook 包裹Button 组件

//Index.js

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

//引入按钮组件
import {Button}  from 'antd';

const  Index = () => { 

   const [count, setCount] = useState(0); 
     
  //使用useCallback 方法包裹 第二个参数我们给空数组 让这个函数永远不会更新
  //注意这个函数永远不会更新的话 setCount 就必须写成funtion 不然拿不到想要的count状态
  const onClick = useCallback(()=> { 
    setCount(prevState => prevState + 1)
  }, [])  
  
  console.log('Index组件渲染')
  
  return <>
      <p>count:{count}</p>
	 
     {/* 使Button组件也永远不要更新 */}
     { useMemo(()=><Button onClick={onClick}>加1</Button> , []}) }
  </>
}
export default Index;

知识延伸:
了解useCallback的使用即可,在项目中考虑到了优化问题,所以将useMemoizedFn来替换useCallback,原因:
很多时候useCallback函数组件props的一部分,因为每次渲染的时候都会重新创建callback导致函数的引用不同(引用地址,看不懂的可以去了解一下js原理,就能稍稍理解些意思了),所以触发了组件的重渲染。然后一旦函数使用useCallback包裹,则要面对声明式依赖项的问题,对于一个内部捕获了很多的state的函数,写依赖项非常容易写错,因此引发bug。所以,多数场景下只需要维持函数引用的情况下使用useCallback。否则,建议使用useMemoizedFn来进行替代useCallback,这样既能保持引用,又不用声明依赖项。
既能保持函数引用地址不变,又不用声明依赖项,而内部变量还可以捕获最新的state(useMemoizedFn,useRef,useMemo)
useMemo
useMemo需要声明依赖项,而memo不需要
把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算

单独使用 memo 也可以搞定 useCallback + useMemo组合。
但是需要注意:当 memo 第二个参数返回 true 时候组件将不会被更新,也就是上一次的 props 的更新将不会用到组件中,可能会造成一些奇怪的问题。所以如果你控制不住的话,最好不要使用。

//Button.js 组件  
const Button = (props) => {   

   console.log('Botton组件渲染 --memo包裹')
   
   return <button onClick={props.onClick}>
       {props.children}
   </button>
}

export default memo(Button, (prevProps, nextProps)=>{	
   //可以使用prevProps, nextProps进行一些逻辑判断
   return true
})

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值