上篇我們了解 setState
為非同步,而此篇將會舉一個setState
踩雷的例子並且告訴大家如何改進。
上篇程式碼,當我們按了按鈕一次,UI 數字就會跟著 +1
increment() {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<div>counter - {this.state.count}</div>
<button onClick={() => this.incrementFive()}>button</button>
</div>
)
}
把新增的 increment 方法放進 function FiveIncrement 呼叫五次
increment() {
this.setState({
count: this.state.count + 1
},
() => {
console.log('callback value', this.state.count)
})
console.log(this.state.count);
}
incrementFive() {
this.increment();
this.increment();
this.increment();
this.increment();
this.increment();
}
render() {
return (
<div>
<div>counter - {this.state.count}</div>
<button onClick={() => this.incrementFive()}>button</button>
</div>
)
}
}
預期按按鈕一次等於呼叫五次應該得到數字5,為何卻得到數字 1?
React 可以將多個
setState()
呼叫批次處理為單一的更新,以提高效能。
什麼意思呢?
以上方程式碼舉例: incrementFive(),React為了提高效能,只會呼叫一次 setState()
也就是只呼叫一次increment(),因此數字才會只增加 1。
用 preState
取得上一個 state,而不是用 this.state
。
increment() {
this.setState(prevState => ({
count: prevState.count + 1
}))
console.log(this.state.count);
}
程式碼大概會長以下這樣:
this.setState((prevState, props) => ({
count: prevState.count + addValue(props)
}))
此篇其實是在一個 youtube 看到的範例,過去沒有發現是因為我都把 setState
這個動作當作一個聰明的組件在執行 ; 同時也會新增一個笨的組件當作 UI 的部分。
以目前我們公司專案,會有以下兩個組件:
SmartCounter.js
做較複雜的動作 ex. setStateDumbCounter.js
簡單的動作 ex. UI 呈現DumbCounter
會接收來自 SmartCounter
的 setState 資料,且因為是由上而下的資料流,此時子組件的DumbCounter
會把來自父組件 SmartCounter
的 state 的資料變成 props,近而比較好利用。