React 中 memo 的实现原理

f1b56e4b1d5c495d8f04e9077cb161d5.png

当一个组件的props或state变更,React 会将最新返回的元素与之前渲染的元素进行对比,以此决定是否有必要更新真实的 DOM,当它们不相同时 React 会更新该 DOM。

如果渲染的组件非常多时可以通过覆盖生命周期方法 shouldComponentUpdate 来进行优化 shouldComponentUpdate 方法会在重新渲染前被触发。其默认实现是返回 true,如果组件不需要更新,可以在shouldComponentUpdate中返回 false 来跳过整个渲染过程。其包括该组件的 render 调用以及之后的操作。

PureComponent通过prop和state的浅比较来实现shouldComponentUpdate。

import React from 'react';
import {Button,message} from 'antd';
import PureComponent from './PureComponent';
export default class App extends PureComponent{
  state = {
    title:'计数器',
    number:0
  }
  add = ()=>{
    this.setState({number:this.state.number+parseInt(this.amount.value)});
  }
  render(){
    console.log('App render');
    return (
      <div>
        <Title2 title={this.state.title}/>
        <Counter number={this.state.number}/>
        <input ref={inst=>this.amount = inst}/>
        <button onClick={this.add}>+</button>
      </div>
    )
  }
}
class Counter extends PureComponent{
  render(){
    console.log('Counter render');
    return (
     <p>{this.props.number}</p>
    )
  }
}
//类组件可以用继承
class Title extends PureComponent{
  render(){
    console.log('Title render');
    return (
     <p>{this.props.title}</p>
    )
  }
}
//函数组件可以和memo
const Title2 = React.memo(props=>{
  console.log('Title2 render');
  return  <p>{props.title}</p>;
});


//memo的实现
function memo(func){
  class Proxy extends PureComponent{
    render(){
      return func(this.props);
    }
  }
  return Proxy;
}
//memo的另一种实现 接收一个函数组件
function memo2(Func){
  class Proxy extends PureComponent{
    render(){
      return <Func {...this.props}/>
    }
  }
  return Proxy;
}

上面的代码在实现 memo 中使用了 PureComponent,那么重点我们实现一下这个组件。

import React from 'react';
function shallowEqual(obj1,obj2){
    if(obj1 === obj2){
        return true;
    }
    if(typeof obj1 != 'object' || obj1 === null ||typeof obj2 != 'object' || obj2 === null ){
        return false;
    }
    let keys1 = Object.keys(obj1);
    let keys2 = Object.keys(obj2);
    if(keys1.length != keys2.length){
        return false;
    }
    for(let key of keys1){
        if(!obj2.hasOwnProperty(key) || obj1[key] !== obj2[key]){
            return false;
        }
    }
    return true;
}
export default class PureComponent extends React.Component{
    isPureReactComponent = true
    shouldComponentUpdate(nextProps,nextState){
        return !shallowEqual(this.props,nextProps)||!shallowEqual(this.state,nextState)
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值