不要突变(mutate) props 或 state 的值是什么意思

在自学react的时候看到这么一段话 不太明白。能解释一下么。
如果 props 和 state 属性存在更复杂的数据结构,这可能是一个问题。例如,我们编写一个 ListOfWords 组件展现一个以逗号分隔的单词列表,在父组件 WordAdder ,当你点击一个按钮时会给列表添加一个单词。下面的代码是不能正确地工作:

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() {
    // 这个部分是不好的风格,造成一个错误
    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 与新的 this.props.words 之间进行前比较。因此在 WordAdder 组件中 handleClick 的代码会突变 words 数组。虽然数组中实际的值发生了变化,但旧的 this.props.words 和新的 this.props.words 值是相同的,即使 ListOfWords 需要渲染新的值,但是还是不会进行更新。
不可变数据的力量
避免这类问题最简单的方法是不要突变(mutate) props 或 state 的值。例如,上述 handleClick 方法可以通过使用 concat 重写:

handleClick() {
  this.setState(prevState => ({
    words: [...prevState.words, 'marklar'],
  }));
};
阅读 2k
1 个回答

就是下面这些代码有问题

const words = this.state.words;
words.push('marklar');
this.setState({words: words});

应该写成

const words = [...this.state.words];
words.push('marklar');
this.setState({words: words});

也就是说要修改一个Array或Object时,应该先clone一个出来,然后再setState回去
不然React不知道你改没改,React不是通过复杂比较来监听state的变化的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题