memo,useMemo和useCallback的使用

关于react项目的优化,react提供了memo,useMemo和useCallback

下面来看看具体怎么使用吧。

React.memo

父元素触发更新后,其子元素也会跟着更新;但是有时候子元素确实没必要重新渲染,故使用 React.memo 可减少重新渲染次数。
使用格式:

// 使用格式
const MyComponent = (props) => {
  /* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
  /*
  如果把 nextProps 传入 render 方法的返回结果与
  将 prevProps 传入 render 方法的返回结果一致则返回 true,
  否则返回 false
  */
}
export const MyComponentMemo = React.memo(MyComponent, areEqual);

一个简单的栗子:
运行可看出:在加载完成后打印 SecondChild子组件? 的次数明显多于 子组件?
并且每次点击按钮加1时,即使 SecondChild 组件没有依赖 count 还是会打印 SecondChild子组件?,说明在重新渲染,但是 Child 组件则不会。(是不是挺好理解的表情🤣

import React, { useState, useEffect, useMemo } from 'react'
const Child = React.memo((props) => {
    console.log('子组件?')
    return(
        <div>我是一个子组件</div>
    );
})
const SecondChild = (props) => {
    console.log('SecondChild子组件?')
    return(
        <div>我是第二个子组件</div>
    );
}
const Page = () => {
    const [count, setCount] = useState(0);
    return (
        <>
            <button onClick={(e) => { setCount(count+1) }}>加1</button>
            <p>count:{count}</p>
            <Child />
            <SecondChild />
        </>
    )
}
export default Page

useMemo

看到 useMemo,想着会不会跟 React.memo有啥关系,其实它们两个是可以配合着一起使用的。
useMemo 的格式跟 useEffect 是一样的,他们之间最大的区别是 useEffect 会用于处理副作用,而useMemo 是其依赖的变量发生改变时再次执行,然后返回缓存的变量;另外 useMemo 会在组件第一次渲染的时候执行;

import React, { useState, useEffect, useMemo, useCallback } from 'react'
const Child = React.memo((props) => {
    console.log('子组件?')
    return(
        <>
            <div>我是一个子组件, number={props.number}</div>
        </>
    );
})
const SecondChild = (props) => {
    console.log('SecondChild子组件?')
    return(
        <div>我是第二个子组件</div>
    );
}
const Page = () => {
    const [count, setCount] = useState(0);
    const [number, setNumber] = useState(0);
    // 返回的是一个值
    const sum = useMemo(() => {
        console.log("sum")
        return count * count
    }, [count])
    const square = () => {
      console.log("square")
      return count * count
    }
    return (
        <>
            <button onClick={(e) => { setCount(count+1) }}>加1</button>
            <p>count:{count}</p>
            <button onClick={(e) => { setNumber(number+1) }}>加1</button>
            <p>number:{number}</p>
            <div>count平方sum:{sum}</div>
            <div>count平方square:{square()}</div>
            <Child number={number} />
            <SecondChild />
        </>
    )
}
export default Page

运行上面的例子,可以发现,当 count 加一时,会打印 sumsquare;当 number 加一时,只会打印 square ;所以如果获取的数是很耗性能时,使用 useMemo 可以避免性能不必要的浪费;

useCallback

如果你学会了 useMemo,那么 useCallback 你也可以轻松掌握;useCallbackuseMemo 是一样使用的,不同的是 useCallback 返回的是缓存的函数;

import React, { useState, useEffect, useMemo, useCallback } from 'react'
const Child = React.memo((props) => {
    console.log('子组件?')
    const [count, setCount] = useState(0);
    // 监听getValue的改变或者直接getValue()
    /* useEffect(() => {
        setCount(props.getValue())
    }, [props.getValue]) */
    return(
        <>
            <div>我是一个子组件, number={props.number}</div>
            <div>获取value: {props.getValue()}</div>
            {/* <div>获取value: {count}</div> */}
        </>
    );
})
const SecondChild = (props) => {
    console.log('SecondChild子组件?')
    return(
        <div>我是第二个子组件</div>
    );
}
const Page = () => {
    const [count, setCount] = useState(0);
    const [number, setNumber] = useState(0);
    const [value, setValue] = useState(0);
    
    // 返回的是一个函数
    const getValue = useCallback(() => {
        console.log("getValue")
        return value
    }, [value])
    /* const getValue = () => {
      return value
    } */
    return (
        <>
            <button onClick={(e) => { setCount(count+1) }}>加1</button>
            <p>count:{count}</p>
            <button onClick={(e) => { setNumber(number+1) }}>加1</button>
            <p>number:{number}</p>
            <button onClick={(e) => { setValue(value+1) }}>加1</button>
            <p>value:{value}</p>
            <Child getValue={getValue} number={number} />
            <SecondChild />
        </>
    )
}
export default Page
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值