鍍金池/ 問(wèn)答/HTML5  HTML/ 不要突變(mutate) props 或 state 的值是什么意思

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

在自學(xué)react的時(shí)候看到這么一段話 不太明白。能解釋一下么。
如果 props 和 state 屬性存在更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),這可能是一個(gè)問(wèn)題。例如,我們編寫(xiě)一個(gè) ListOfWords 組件展現(xiàn)一個(gè)以逗號(hào)分隔的單詞列表,在父組件 WordAdder ,當(dāng)你點(diǎn)擊一個(gè)按鈕時(shí)會(huì)給列表添加一個(gè)單詞。下面的代碼是不能正確地工作:

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() {
    // 這個(gè)部分是不好的風(fēng)格,造成一個(gè)錯(cuò)誤
    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>
    );
  }
}

問(wèn)題是 PureComponent 只進(jìn)行在舊的 this.props.words 與新的 this.props.words 之間進(jìn)行前比較。因此在 WordAdder 組件中 handleClick 的代碼會(huì)突變 words 數(shù)組。雖然數(shù)組中實(shí)際的值發(fā)生了變化,但舊的 this.props.words 和新的 this.props.words 值是相同的,即使 ListOfWords 需要渲染新的值,但是還是不會(huì)進(jìn)行更新。
不可變數(shù)據(jù)的力量
避免這類問(wèn)題最簡(jiǎn)單的方法是不要突變(mutate) props 或 state 的值。例如,上述 handleClick 方法可以通過(guò)使用 concat 重寫(xiě):

handleClick() {
  this.setState(prevState => ({
    words: [...prevState.words, 'marklar'],
  }));
};
回答
編輯回答
青裙

就是下面這些代碼有問(wèn)題

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

應(yīng)該寫(xiě)成

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

也就是說(shuō)要修改一個(gè)Array或Object時(shí),應(yīng)該先clone一個(gè)出來(lái),然后再setState回去
不然React不知道你改沒(méi)改,React不是通過(guò)復(fù)雜比較來(lái)監(jiān)聽(tīng)state的變化的

2017年7月31日 05:47