首页 > 解决方案 > 为什么 React 浅比较不会注意到引用的变化?

问题描述

在 reactjs.org,在这个页面https://fr.reactjs.org/docs/optimizing-performance.html,我不明白这部分:

class ListOfWords extends React.PureComponent {
  render() {
    return <div>{this.props.words.join(',')}</div>;
  }
}

class WordAdder extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      words: ['marklar']
    };
    this.handleClick = this.handleClick.bind(this);
  }

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

  render() {
    return (
      <div>
        <button onClick={this.handleClick} />
        <ListOfWords words={this.state.words} />
      </div>
    );
  }
}

问题是 PureComponent 会在 this.props.words 的新旧值之间做一个简单的比较。由于此代码更改了 WordAdder 的 handleClick 方法中的 words 数组,因此 this.props.words 的旧值和新值将比较相等,即使数组中的实际单词已更改。ListOfWords 因此不会更新,即使它有应该呈现的新词。

我从handleClick() 中了解到,this.state.words 物理上发生了变化(以前的对象被一个新的对象替换,所以是新的指针)。浅比较应该注意到它,因为它会注意到任何道具的内部变化,不是吗?为什么不是这里的情况?

标签: reactjs

解决方案


handleClick(), this.state.words 物理变化(之前的对象被新的替换了,所以新的指针)

这不是真的。我们来看看这个方法的作用:

handleClick() {
  // This section is bad style and causes a bug
  const words = this.state.words; // words is now a reference to the array
  words.push('marklar'); // we add an item to the array. reference doesn't change
  setState({words: words}); // we update state setting words to the same array reference
}

现在,在下一次重新渲染时,react 比较之前的words数组和新words的数组,发现数组引用是相同的。

“浅比较”不检查数组内的内容。它检查引用以查看它是否是新的


推荐阅读