react原理分析--this.state修改引起的重新渲染


整理向,非原創,目的是整理出淺顯易懂的方向性說明.

 

比如現有

this.state={name:"小明",age:18}

 

我們說修改組件的狀態要用this.setState()來實現.這里有兩個問題

1.為什么?我直接用this.state.age=17能不能實現重新渲染?

不能.因為它只是改變了這個組件當前的狀態,並沒有調用render().

 

2.this.setState()的原理是什么?

react中有一個原則:有變化,就一定返回一個新對象;沒變化,原對象不做變化直接返回;

結合這個原則我們來分析一下原理:

參數:

this.setState()有三個參數:分別是this.state、nextState和callback.

       其中,第一個參數是默認已經給的,為什么還要提出來是為了方便理解.

       第二個參數是新狀態,也就是我們期望組件能達到的狀態.有多種方式.傳一個對象或者傳一個返回對象的函數.最終效果就是傳一個對象.

this.setState({age:17})

      第三個參數是設置成功之后的回調函數.

返回值:

this.setState()的返回值是一個新的對象,也就是說是一個新的狀態.它使用了Object.assign(),將已修改的屬性添加進去.而不是覆蓋.

 

this.state里面有兩個屬性,如果我   this.setState({age:17}) 這么操作會不會導致this.state里面沒有了"name"屬性?

不會!我們上面剛說,this.setState()是返回一個新的對象,它會把有變動的改變成變動后的值,沒有變動的保留.所以,你完全可以用這個方法去改變其中的某一個值.

 

接下來我們重點分析內部的原理:

首先,需要根據原來的this.state和傳進來的參數來判斷是否批量更改(是否批量差了一個收集待改組件的步驟),而這里的this.state是我之前說的默認傳進來的.

然后,再根據this.state來計算nextstate. (shouldComponentUpdate()根據拿到的nextstate來返回一個布爾值,true則進行下一步,false,則下一步不執行.然后就進入componentWillUpdate)

接着render()出一個next組件,

最后根據diff算法進行更新渲染. 結束后進入生命周期函數componentDidUpdate()

這里也有幾個問題:

(1)假如我調用this.setState()設置的值跟之前一樣的,會不會重新渲染一次?

會!因為shouldComponentUpdate()默認肯定返回true,所以一定會往下執行.那為什么我要是根據nextstate返回一個布爾值呢?因為我們可以手動通過這種方式來控制render()來減少無用功,這是shouldComponentUpdate()的功能,只不過沒有默認執行而已.

 

(2)假如我進行多次this.setState()的操作,而且都是同一個屬性修改最終以哪次為主?

 

function stateChange() {
      this.setState({age: this.state.age + 1});
      this.setState({age: this.state.age + 1});
      this.setState({age: this.state.age + 1});
}

 

這里情況比較復雜,大體上可以理解為在react的體制內setState()是異步操作,所以最后this.state.age最終還是只加了1,比如onClick()這種react原生的事件中.但是體制外的是同步操作.最終會加3.

 

(3)為啥console.log()拿不到最新的this.state?

如第(2)點所說,setState()是異步操作.還記得上面所說this.setState()還有一個參數是回調函數嗎?所以需要在this.setState()的參數里面再傳一個回調函數,在函數中打印就能得到this.state.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM