公司的項目使用的是react+redux+antd的技術(shù),作為新手我在不斷學(xué)習(xí),整理一下react+redux的內(nèi)容尽纽,作為項目入門的記錄。
網(wǎng)上有很多有趣清晰的說明文章童漩,參考了幾篇列一下:
https://zhuanlan.zhihu.com/p/20641377?columnSlug=haochuan
https://github.com/jasonslyvia/a-cartoon-intro-to-redux-cn
http://www.ruanyifeng.com/blog/2015/03/react.html(阮大神的文章需要好好學(xué)習(xí)下的)
http://www.runoob.com/react/react-state.html?
下面是關(guān)于react和redux的學(xué)習(xí)內(nèi)容摘要
react:
特點(diǎn):
1.組件化——JSX語法弄贿;
2.單向數(shù)據(jù)流------數(shù)據(jù)一旦更新,就將重新渲染整個APP---redux矫膨;
3.虛擬DOM樹———更新時重建DOM樹差凹,找到與上一個版本的DOM差異,計算最新DOM更新操作侧馅,批量進(jìn)行更新----可以直接渲染特定的頁面而不是整個APP危尿;
React 把組件看成是一個狀態(tài)機(jī)(State Machines)。通過與用戶的交互馁痴,實現(xiàn)不同狀態(tài)谊娇,然后渲染 UI,讓用戶界面和數(shù)據(jù)保持一致罗晕。這個渲染過程為:交互—>狀態(tài)改變—>實現(xiàn)不同狀態(tài)—>渲染UI济欢。React 里赠堵,只需更新組件的 state,然后根據(jù)新的 state 重新渲染用戶界面(不要操作 DOM)法褥。
舉個例子茫叭。最近做的一個小需求,通過訂單的狀態(tài)更改訂單的類型列表半等,出了bug揍愁,后來在前輩指導(dǎo)下修正了。貼一部分代碼說明一下:
handleOrderTypeChange= (value) => {
? ? this.setState({orderType: value});
? ? this.props.form.setFieldsValue({order_status: orderTypeToStatus[value] 酱鸭?orderTypeToStatus[value][0] : orderStatus[0].name});
}
//在view中進(jìn)行更新
render{ ……
? ? {getFieldDecorator('order_type',{initialValue:"",onChange:this.handleOrderTypeChange}) ? ? ? ? ?(
? ? ? ? {this.orderOptions()}
? ? )}
}
這部分通過在函數(shù) handleOrderTypeChange 中吗垮,使用this.setState 方法修改狀態(tài)值垛吗,然后使用antd的方法 setFieldsValue凹髓,將ordertype的內(nèi)容推進(jìn)文本框即可。這個例子體現(xiàn)了react的組件化的特點(diǎn)怯屉。
redux:
從上述對react的特點(diǎn)介紹蔚舀,可以看出,
1. react的數(shù)據(jù)是單向流動的锨络,沒有數(shù)據(jù)向上回溯的能力赌躺,也就是說數(shù)據(jù)只能單向向下分發(fā),或者自行內(nèi)部消化羡儿。
2. react根本無法讓兩個組件相互交流礼患,互相使用數(shù)據(jù),然后這時候不通過DOM溝通(也就是React體制內(nèi))解決的唯一辦法就是提升state掠归,將state放到共有的父組件中來管理缅叠,再作為props分發(fā)回子組件。
3. 子組件改變父組件state的辦法只能是通過onClick觸發(fā)父組件聲明好的回調(diào)虏冻,也就是父組件提前聲明好函數(shù)或方法作為契約描述自己的state將如何變化肤粱,再將它同樣作為屬性交給子組件使用。
4. 為了面臨所有可能的擴(kuò)展問題厨相,最容易想到的辦法就是把所有state集中放到所有組件頂層领曼,然后分發(fā)給所有組件。
為了有更好的state管理蛮穿,就需要一個庫來作為更專業(yè)的頂層state分發(fā)給所有React應(yīng)用庶骄,這就是Redux。
讓我們回來看看重現(xiàn)上面結(jié)構(gòu)的需求:
a. 需要回調(diào)通知state (等同于回調(diào)參數(shù)) -> action
b. 需要根據(jù)回調(diào)處理 (等同于父級方法) -> reducer
c. 需要state (等同于總狀態(tài)) -> store
因此践磅,redux的三要素就是 action单刁,reducer,store:
action:純聲明式的數(shù)據(jù)結(jié)構(gòu)音诈,只提供事件的所有要素幻碱,不提供邏輯绎狭。
reducer:一個匹配函數(shù),action的發(fā)送是全局的:所有的reducer都可以捕捉到并匹配(比如使用switch...case結(jié)構(gòu))與自己相關(guān)與否褥傍,相關(guān)就拿走action中的要素進(jìn)行邏輯處理儡嘶,修改store中的狀態(tài),不相關(guān)就不對state做處理原樣返回恍风。
store:負(fù)責(zé)存儲狀態(tài)并可以被react api回調(diào)蹦狂,發(fā)布action.
具體工作的時候,流程為:
通過view(state)觸發(fā)action朋贬,通過reducer匹配action凯楔,通過在reducer中改變state,最終反應(yīng)到view中锦募;
流程圖為:
view ---> action ---> reducer ---> store(state) ---> view
當(dāng)然一般不會直接把兩個庫拿來用诊赊,還有一個binding叫react-redux, 提供一個Provider和connect民逼。
Provider是一個普通組件,可以作為頂層app的分發(fā)點(diǎn),它只需要store屬性就可以了四濒。它會將state分發(fā)給所有被connect的組件缭嫡,不管它在哪里痛侍,被嵌套多少層钥弯。
connect是真正的重點(diǎn),它是一個柯里化函數(shù)垂寥,意思是先接受兩個參數(shù)(數(shù)據(jù)綁定mapStateToProps和事件綁定mapDispatchToProps)颠黎,再接受一個參數(shù)(將要綁定的組件本身):
mapStateToProps:構(gòu)建好Redux系統(tǒng)的時候,它會被自動初始化滞项,但是你的React組件并不知道它的存在狭归,因此你需要分揀出你需要的Redux狀態(tài),所以你需要綁定一個函數(shù)蓖扑,它的參數(shù)是state唉铜,簡單返回你關(guān)心的幾個值。
mapDispatchToProps:聲明好的action作為回調(diào)律杠,也可以被注入到組件里潭流,就是通過這個函數(shù),它的參數(shù)是dispatch柜去,通過redux的輔助方法bindActionCreator綁定所有action以及參數(shù)的dispatch灰嫉,就可以作為屬性在組件里面作為函數(shù)簡單使用了,不需要手動dispatch嗓奢。這個mapDispatchToProps是可選的讼撒,如果不傳這個參數(shù)redux會簡單把dispatch作為屬性注入給組件,可以手動當(dāng)做store.dispatch使用。這也是為什么要科里化的原因根盒。
做好以上流程Redux和React就可以工作了钳幅。簡單地說就是:
1.頂層分發(fā)狀態(tài),讓React組件被動地渲染炎滞。
2.監(jiān)聽事件敢艰,事件有權(quán)利回到所有狀態(tài)頂層影響狀態(tài)。
最基礎(chǔ)的一點(diǎn)探索册赛,未完待續(xù)钠导。。