在react中,修改狀態如果直接使用this.state,不會引起組件的重新渲染,需要通過 this.setState來對組件的屬性進行修改。
1、this.setState的兩種定義方式
定義初始狀態
1
|
state = { count: 0 }, |
如果此時有一個按鈕,點擊按鈕讓計數加1,我們可以有兩種寫法
(1)傳遞對象
1
|
this .setState({ count: this .state.count + 1}) |
(2)傳遞函數
1
|
this .setState((state, props) => ({ count: count + 1})) |
2、setState的兩種方式有什么不同?
如果變更的state的值需要依賴于上一次的state的值,這種情況就需要用到函數的形式,比如以下這種情況
1
2
3
4
5
|
addCount(){ this .setState({ count: this .state.count + 1}) this .setState({ count: this .state.count + 1}) this .setState({ count: this .state.count + 1}) } |
此時只會執行一次+1的操作,因為在React內部,會將多次setState合并操作,新的state由 Object.assgin({}, {count: 0}, { count: 1}) 合并所得,以上賦值會執行三次,但因為count的值沒有更新,所以最終執行的結果只+1,如果setState的賦值是函數,那情況就不一樣了
1
2
3
4
5
|
addCount(){ this .setState((state, props) => ({ count: count + 1})) this .setState((state, props) => ({ count: count + 1})) this .setState((state, props) => ({ count: count + 1})) } |
這樣的操作會得到+3的效果,因為React會進行判斷,如果傳入的是函數,那么將執行此函數,此時count的值就已經被修改了
3、setState是同步還是異步的?
☆☆☆☆☆ 是異步的
(1) 即我們通過this.setState修改了狀態之后,在它的下一行輸出state的值并不會得到新的值
(2) 為什么是異步?
有兩個原因,一是提高效率,每次修改state的值都會造成render的重新渲染,將多次修改state的值合并統一更新可以提高性能;二是render的更新會晚一些,如果render中有子組件,子組件的props依賴于父組件的state,props和state就不能保持一致
(3) 如何獲取異步時的state值?
① 在setState的回調函數中
1
2
3
|
this .setState({ count: this .state.count + 1}}, ()=>{ console.log( this .state.count)}) |
② 在componentDidUpdate中獲取
1
2
3
|
componentDidUpdate(){ console.log( this .state.count) } |
☆☆☆☆☆ 是同步的
(1) 即我們通過this.setState修改狀態之后,在它的下一行輸出state是新的值
(2) 什么場景下是同步的?
① 原生js獲取dom元素,并綁定事件
1
2
3
4
5
6
7
8
|
<button id= "addBtn" >點我+1</button> componentDidMount(){ const addBtn = document.getElementById( 'addBtn' ) changeBtn.addEventListener( 'click' ,()=>{ this .setState({ count: this .state.count + 1}) console.log( this .state.message) }) } |
② 計時器 setTimeout
1
2
3
4
5
|
<button onClick={ e => this .addOne() }>點我+1</button> addOne(){ setTimeout(()=>{ this .setState({ count: this .state.count + 1 }) console.log( this .state.count ) },0) } |
到此這篇關于React中setState的使用與同步異步的使用的文章就介紹到這了,更多相關React setState同步異步內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://segmentfault.com/a/1190000039412713