前端小誌(轉型中)

一個用來記錄人老會忘記的地方

React的setState非同步行為2

2018年01月16日
都2018了,現在的感覺是redux統一天下。不過在清書籤頁,希望是近期內最後一次深入了解state。

因為state的改變會觸發re-render,而re-render是一個expensive的行為,所以React做了batch,在一連串state改變中只會render一次。

function doSomething() {
  this.setState({
    something: thisThing,
  });
  if (condition) {
    this.setState({
      something: thatThing,
    });
  }
}

有時候就是會寫出這種code(尤其是在lifecyle componentWillReceiveProps之類的)

但因為非同步所以會拿到不對的state值,所以大家很喜歡在這事上討論(打轉)。

常見解決辨法

  1. update完成後,callback,看這裡

  2. 校正lifecyle,在正確的lifecycle裡面呼叫setState。

3. 直接呼叫callback,介紹一下

setState是可以直接帶入一個callback的

this.setState((prevState, currentProps) => {
  reurn { prevState, something: currentProps.something }
})

不過這一點都不能解決非同步state問題(還是會拿到舊的state)

很認真的看了文章以後,我是覺得結論有點難懂

,結論是說,將function移出class會讓需要修改的值變得更明確(agree)。但是仍然有小機率會用到舊的state(這邊不太理解小機率...)

function incrementFooBy(delta) {
    return (previousState, currentProps) => {
        return { ...previousState, foo: previousState.foo + delta };
    };
}
class MyComponent extends React.Component {
    onClick = () => {
        this.setState(incrementFooBy(42));
    }
    render() {
        return <button onClick={onClick}>click me</button>;
    }
}

不過最大的變數應該是react setstate行為以後可能會全部重新定義吧。

截錄另一篇文章兩段話

Honestly, the current batching strategy comes with a set of problems right now. I'm hesitant to expand on it's API before we're sure that we're going to keep the current model. I think of it as a temporary escape until we figure out something better.

問題的根源在於現有的 batching 策略,實話實說,這個策略帶來了一系列問題。也許這個在後期後有調整,在 batching 策略是否調整之前,盲目的擴充 setState 接口只會是一個短視的行為。

In my experience, whenever I'm tempted to use setState callback, I can achieve the same by overriding componentDidUpdate (and/or componentDidMount).

對此,Redux 原作者 Dan Abramov 也發表了自己的看法。他認為,以他的經驗來看,任何需要使用 setState 第二個參數 callback 的場景,都可以使用生命周期函數 componentDidUpdate (and/or componentDidMount) 來覆寫。

如果確認專案是使用redux flux等,state只用來處理一小部份short-time data,那我是覺得真正遇到問題的時候再研究啦。


展開Disqus
分類
最近文章
友站連結
© 2019 Ernie Yang