天天看点

React.memo 和 useCallBack

页面略微丑陋,是我从为知笔记粘贴过来的, 原文链接

正常情况下,为了减少子组建中没必要的渲染, 一般会在子组建中 使用 React.memo() 进行包裹, 例如

const Child = ({acount}) => {
    return (
        <button>{acount}</button>    
    )
}

export default React.Memo(Child)
           

这种情况下,只要 传入数据 acount 不变化, 子组建就不会重新渲染

**** 父组件有两种情况,

1)当父组建是类组件时候,即使传入子组件的参数中有函数,子组件使用了 React.memo()进行了包裹, 即使父组件重新render, 子也不会更新,

import Child from 'xxx/xxx/Child';

class Index extends React.Component{
    constructor(props){
        super(props)    
        state = {
            acount: 0        
        }
    }
    
    changeAcount = () => {
        const { acount } = this.state;
        this.setState({
            acount:  acount+1       
        })            
    }
    
    render() {
        const { acount } = this.state;
        const { userList = [] } = this.props;
        return(
          <Button onClick={changeAcount}>+1</Button>
          <span>{acount}</span>
          <Child userList={userList}/>          
        )    
    }
}

// 子组件, 此时没有传入函数, 只是传入了数据,

const Child = ({userList}) => {
    return (
         <Button>小鱼</Button>   
    )
}

export default Child;

// 子组件, 参数同时有数据 和 回调函数
const Child = ({userList, deleDemo}) => {
    return (
         <Button onClick={() => deleDemo()}>小鱼</Button>   
    )
}

export default Child;
           

// 这回可以看到, 父组件在重新setState的时候, 子组件依旧不会重新加载

2)当父组件为函数式组件的情况下, 如果传入子组件中有函数, 即使使用了 React.memo() 包裹,也会造成再次没必要的渲染

// 将上面的 父组件改成函数式组建, 就会发现父组件执行 setState的时候, 子组件重新render了

当父组建为函数式组件的时候,为了防止子组件没必要渲染

import React,{ useCallBack } from 'react';

const Index = (props) => {
    const changeAcount = () => {
        const { acount } = this.state;
        this.setState({
            acount:  acount+1       
        })            
    }
    
    // 这里使用了 useCallBack对函数进行了一次包装, 在父组件执行 setState的时候,子组件不会重新渲染, 因为父组件的每次渲染,函数都是一个新的函数,传入组件会被认为新参数,这里的 useCallBack 相当于做了一个函数的缓存, 子组件在接收的时候 认为参数没变
    const getNameChild = useCallBack((state) => {
            console.log('子组件传入数据', state)
    }, [])
    
    render() {
        const { acount } = this.state;
        const { userList = [] } = this.props;
        return(
          <Button onClick={changeAcount}>+1</Button>
          <span>{acount}</span>
          <Child userList={userList} getName={getNameChild}/>          
        )    
    }
}

export default Index;