React中setState方法說明
setState跟新數據是同步還是非同步?
setState跟新數據是非同步的。
如何用程式碼表現出來是非同步的。
點擊按鈕更新數據,然後去列印這個值看一下
setState跟新數據是非同步的
class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
this.setState({
num: 100
})
console.log('state中的值',this.state.num)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p>顯示的值 {this.state.num }</p>
</div>
)
}
}
ReactDOM.render(
<Father></Father>,
document.getElementById('root')
)

我們發現
當我們使用setState更新數據時候,
然後立刻去獲取更新後的值,我們發現不是我們更新後的值。
而是更新前的值。
這就說明了setState跟新數據是非同步的
因此需要注意的點
由於 setState 跟新數據是非同步的。
因此 setState 後面的程式碼不要依賴於setState前面的。
同一個方法多次調用 setState會怎麼樣
class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
<!-- 第一調用 -->
this.setState({
num: this.state.num+1
})
console.log('state中的值', this.state.num)
<!-- 第二次調用 -->
this.setState({
num: this.state.num + 1
})
console.log('state中的值', this.state.num)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p>顯示的值 {this.state.num }</p>
</div>
)
}
}

我們的結論
在同一個方法中我們調用了兩次setState.
但是最後介面上顯示的不是2;0+1+1=2
而是顯示的1
也就是說雖然多次調用setState,但是最終只會執行一次。
所以只會觸發一次渲染介面。所以介面上顯示的是1
由於介面只觸發一次,所以render函數也只會觸發一次
為什麼多次調用setState最終只會觸發一次渲染介面
這樣做的目的是為了性能的考慮。
比如說你寫了一個循環,循環了1000次;
設計的時候如果讓setState執行1000次;
這樣太浪費性能了。
完全可以讓開發者將最後的結果進行展示。
所以React並不會將setState執行1000次
而是只會執行一次。 render函數也只會執行一次。
非要讓setState多次執行怎麼辦?
有沒有這樣的場景?
第二次的setState需要依賴第一次的setState的結果
舉個簡單的例子:第一次數字從0變為1,第二次1變為10
這個時候我們怎麼辦了?
比著急,有解決的辦法
setState 推薦語法
setState((state, props) => {
參數state,表示最新的state
參數props,表示最新的props
})
需要的是這種語法也是非同步的哈
使用推薦語法實現setState多次執行
class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
<!-- 在這個方法中我們多次調用了setState -->
this.setState((state, props) => {
// state
// props
return {
num: state.num+1
}
})
this.setState((state, props) => {
// state
// props
return {
num: state.num + 10
}
})
console.log('state中的值', this.state.num)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p>顯示的值 {this.state.num }</p>
</div>
)
}
}

setState第二個參數的誕生
剛剛我們在前面發現console.log獲取的值
不是數據更新的後的值。
而是初始值。我們也說了
由於 setState 跟新數據是非同步的。
因此 setState 後面的程式碼不要依賴於setState前面的。
如果我們想獲取 setState更新後的值怎麼辦了?
這個時候我們就需要使用setState的第二個參數。
setState第二個參數的場景
在狀態更新完成(介面完成重新渲染)後立刻執行某一個操作
ps:需要注意的的是不可以不會頁面中的dom
ps:需要注意的的是不可以不會頁面中的dom
this.setState(
(state, props) => {
return {}
},
()=>{
console.log('介面完成重新渲染)後立刻執行某一個操作')
}
)
setState第二個參數的使用
class Father extends React.Component{
state = {
num:0
}
addHandler = () => {
this.setState(
(state, props) => {
return {
num: state.num + 1
}
},
() => {
console.log('獲取setState跟新後的值', this.state.num)
console.log('dom節點',document.getElementById('#name') )
console.log('cont', document.title)
}
)
}
render() {
return (
<div>
<button onClick={this.addHandler}>新增</button>
<p id='name'>顯示的值 {this.state.num }</p>
</div>
)
}
}
ReactDOM.render(
<Father></Father>,
document.getElementById('root')
)
