react的設計思想就是界面由數據驅動,公式:UI = f(data)。UI表明最終渲染的界面,f表示的是一個函數,data就是數據。data能夠來自於組件內部的state,也能夠是props。就是下文中講到的內容。html
1、組件狀態state
組件內的數據分爲兩種
- state 組件內部數據,外部不可見
- props 外部傳入的數據
因此,判斷一個數據應該放在哪裏,用下面的原則:
一、若是數據由外部傳入,放在 props 中;react
二、若是是組件內部狀態,是否這個狀態更改應該馬上引起一次組件從新渲染?若是是,放在 state 中;不是,放在成員變量中。redux
如何修改state:
1 this.state.foo = 'bar'; //錯誤的方式
2 this.setState({foo:'bar'}); //正確的方式
如上面代碼所示,若是隻是修改 this.state,那改了也就只是改了這個對象,其餘的什麼都不會發生;若是使用 setState 函數,那不光修改 state,還能引起組件的從新渲染,在從新渲染中就會使用修改後的 state,這也就是達到根據 state 改變公式左側 UI 的目的。
可是setState並非每次調用都能觸發渲染。React爲了優化渲染,避免每次setState都去渲染而浪費性能,用了任務隊列的方式來解決,屢次setState調用會往隊列裏放多個任務,而後React會選擇合適的時機去處理,當批量處理開始時,會合並多個setState,好比下面:
1 this.setState({count: 1});
2 this.setState({caption: 'foo'});
3 this.setState({count: 2});
最終會被合併爲this.setState({count: 2, caption: 'foo'});因此被合併後屢次的setState只會更新一次,從而只引起一次從新渲染。固然也由於有這個隊列的存在setState在React中沒法保證同步更新state中的數據。注意:setState中的對象合併都是->淺合併設計模式
state的批處理:
能夠這麼理解,當 React 調用某個組件的生命週期函數或者事件處理函數時,React 會想:「嗯,這一次函數可能調用屢次 setState,我會先打開一個標記,只要這個標記是打開的,全部的 setState 調用都是往任務隊列裏聽任務,當這一次函數調用結束的時候,我再去批量處理任務隊列,而後把這個標記關閉。」
那麼如何進行setState的連續操做併產生同步效果?使用函數式setState
setState 的第一個參數爲函數時,任務列表上增長的就是一個可執行的任務函數了,React 每處理完一個任務,都會更新 this.state,而後把新的 state 傳遞給這個任務函數。
1 function increment(state, props) {
2 return {count: state.count + 1};
3 }
4 this.setState(increment);
5 this.setState(increment);
6 this.setState(increment);
2、Redux數據管理工具函數
Redux至關因而全部組件共享的數據store,打破了父子、子父、兄弟組件之間的數據傳遞的路徑,均可以直接去store裏拿。
適合redux的場景:
第一步,看這個狀態是否會被多個 React 組件共享。
所謂共享,就是多個組件須要讀取或者修改這個狀態,若是是,那不用多想,應該放在 Store 上,由於 Store 上狀態方便被多個組件共用,避免組件之間傳遞數據;若是不是,繼續看第二步。
第二步,看這個組件被 unmount 以後從新被 mount,以前的狀態是否須要保留。
舉個簡單例子,一個對話框組件。用戶在對話框打開的時候輸入了一些內容,不作提交直接關閉這個對話框,這時候對話框就被 unmount 了,而後從新打開這個對話框(也就是從新 mount),需求是否要求剛纔輸入的內容依然顯示?若是是,那麼應該把狀態放在 Store 上,由於 React 組件在 unmount 以後其中的狀態也隨之消失了,要想在從新 mount 時重獲以前的狀態,只能把狀態放在組件以外,Store 固然是一個好的選擇;若是需求不要求從新 mount 時保持 unmount 以前的狀態,繼續看第三步。
第三步,到這一步,基本上能夠肯定,這個狀態能夠放在 React 組件中了。
主要掌握點
- Redux 中的基本概念 action、reducer 和 store;
- 使用 react-redux 會應用哪些設計模式;
- 如何設計 Redux 的 Store。
3、Mobx數據管理工具
簡單直接的數據操做,不須要作dispatch,沒必要如redux走一遍嚴格的範式,調用action就能修改數據。並且適合使用多個store,固然使用configure配置能夠禁止直接修改observable數據,只能使用action。
主要掌握點
- Mobx 的基本功能就是「觀察者模式」
- decorator 是「裝飾者模式」在 JavaScript 語言中的實現
- Mobx 一般利用 decorator 來使用
- 如何利用 mobx-react 來管理 React組件的狀態
4、不一樣方式的對比
Redux 認爲,數據的一致性很重要,爲了保持數據的一致性,要求Store 中的數據儘可能範式化,也就是減小一切沒必要要的冗餘,爲了限制對數據的修改,要求 Store 中數據是不可改的(Immutable),只能經過 action 觸發 reducer 來更新 Store。
Mobx 也認爲數據的一致性很重要,可是它認爲解決問題的根本方法不是讓數據範式化,而是不要給機會讓數據變得不一致。因此,Mobx 鼓勵數據乾脆就「反範式化」,有冗餘沒問題,只要全部數據之間保持聯動,改了一處,對應依賴這處的數據自動更新,那就不會發生數據不一致的問題。
主要區別:
- Redux 鼓勵一個應用只用一個 Store,Mobx 鼓勵使用多個 Store;
- Redux 使用「拉」的方式使用數據,這一點和 React是一致的,但 Mobx 使用「推」的方式使用數據,和 RxJS 這樣的工具走得更近;
- Redux 鼓勵數據範式化,減小冗餘,Mobx 允許數據冗餘,但一樣能保持數據一致。
適用場景:
Mobx 應用小而簡單 快速開發
Redux 大而複雜 須要長期維護
固然隨着react的不斷更新發展,也有可能出現react內部的數據共享機制。