React高级教程(es6)——(4)ShouldComponentUpdate的用法

本文介绍React的ShouldComponentUpdate(SCU)方法,用于控制组件何时更新。常见SCU用法包括根据props和state的变化进行组件更新。当组件复杂,状态变量增多时,可使用React.PureComponent进行浅比较。然而,当props和state中的对象或数组发生变化时,浅比较可能失效。为解决这个问题,可以通过创建新对象避免引用问题,或者使用Immutable.js等插件进行深层比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介:ShouldCompleteUpdate,下文简称SCU,就是指明什么时候component(组件)需要进行更新。

1.常见的SCU的用法:

(1)比如在下面的例子中,组件中只有2个值,props.color和state.count可以发生改变,我们可以这样

使用SCU。

class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    <button
      color={this.props.color}
      onClick={() => this.setState(state => ({count: state.count + 1}))}>
      Count: {this.state.count}
    </button>
  }
}

在上述代码中,组件仅仅会校验prop.color和state.count,如果这些值都不会改变,那么组件就不会有更新。

(2)如果组件更加复杂,拥有的状态变量更多

当组件复杂化,拥有状态变多时,我们需要设计一种模式,对所有的props变量和state变量,做一个“shallow comparison(浅比较)”,这样会使得SCU函数冗杂化,为了解决该问题,React给了我们提供了另一个继承方法——React.PureComponent:

class CounterButton extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  render() {
    <button
      color={this.props.color}
      onClick={() => this.setState(state => ({count: state.count + 1}))}>
      Count: {this.state.count}
    </button>
  }
}

在大多数的情况下,”shallow comparison(浅比较)”是有意义的,因此在大部门情况下我们可以用React.PureComponent来代替SCU,但是当props和state中的变量发生突变的情况下,“shallow comparison”会失效,因此在props和state的变量发生突变的情况下,不能通过React.PureComponent来更新组件。

  1. shallow comparison失效的情况

shallow comparion在js中:

var x=[1,2];
var y=x;
x.push(3);
console.log(x==y)//输出true
var x={a:1};
var y=x;
x.b=2;
console.log(x==y)//输出true

从上面我们可以看出,shallow comparison不能进行深层比较的原因是,js中数组和对象的本质都是Object,一旦赋值y=x后,无论x如何变化,x,y都会只想的是同一个对象。

3.如何解决shallow comparison失效的问题

(1)

失效状态1:

 handleClick() {
    // This section is bad style and causes a bug
    const words = this.state.words;
    words.push('marklar');
    this.setState({words: words});
  }

解决方法:

handleClick() {
  this.setState(prevState => ({
    words: prevState.words.concat(['marklar'])
  }));
}

失效状态2:

function updateColorMap(colormap) {
  colormap.right = 'blue';
}

解决方法:

function updateColorMap(colormap) {
  return Object.assign({}, colormap, {right: 'blue'});
}

本质:解决方法的本质是生成了一个新的对象,新对象与原对象比较一定返回的是false。

(2)另一种方法是通过插件Immutable.js解决,不详细描述。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值