小白路程之----初学React语法栈之redux与react-redux
Redux
1、核心概念
????Redux的主要目的,即集中且可預(yù)測的管理數(shù)據(jù)。集中管理指:將所有需要管理的數(shù)據(jù)放到一個store中進(jìn)行管理。可預(yù)測指:數(shù)據(jù)的變化可以預(yù)測。為了實(shí)現(xiàn)這個功能,Redux將數(shù)據(jù)的操作全部交給了reducer來管理,而在action中定義數(shù)據(jù)處理的動作。這樣當(dāng)你的數(shù)據(jù)處理動作action傳過來時,store便已經(jīng)知道將要對數(shù)據(jù)進(jìn)行的處理。在Redux中主要有三個內(nèi)容,分別是store,action以及reducer。
- 1、store:連接reducer和state,并且為處理數(shù)據(jù)提供接口,
- 2、action:描述對數(shù)據(jù)處理的動作,是store 數(shù)據(jù)的唯一來源
- 3、reducer:接收 state 和 action,并返回新的 state 的函數(shù)。
三大原則
- 單一數(shù)據(jù)源:整個應(yīng)用的state被儲存在一棵object tree中,并且object tree只存在于唯一一個store中。
避免數(shù)據(jù)被修改,以及確定唯一的修改數(shù)據(jù)的方法就是訪問store。
- State 是只讀的:唯一改變state的方法就是觸發(fā)action,action是一個用于描述已發(fā)生事件的普通對象。
對store外部來說,只能訪問state數(shù)據(jù),而不能修改,確保state不被其他的方法修改,而所有的數(shù)據(jù)修改方法都被reducer集中化處理。
- 使用純函數(shù)來執(zhí)行修改:為了描述 action 如何改變 state tree,你需要編寫 reducers。
action描述處理數(shù)據(jù)這件事,對數(shù)據(jù)的處理是在reducer內(nèi)完成的,接收先前的state以及action,并返回新的state。
使用Redux的步驟
以counter計數(shù)器為例,
1、創(chuàng)建state對象
????對應(yīng)第一個原則,單一數(shù)據(jù)源,在Redux中所有的對象都被保存在一個單一的對象中,
在store.js文件中先定義所需的對象,如下:
const state = {counter:99, } 復(fù)制代碼2、定義action
- 官網(wǎng):Action是把數(shù)據(jù)從應(yīng)用傳到store的有效載荷。它是store數(shù)據(jù)的唯一來源。一般來說你會通過store.dispatch()將action傳到store。
- 簡單來說就是要求store處理數(shù)據(jù)的信號,對于不同的信號reducer對數(shù)據(jù)進(jìn)行不同的處理。
實(shí)現(xiàn)加減操作,定義如下:
//實(shí)現(xiàn)加的increment操作: const increment ={type = 'INCREMENT' } // 減操作的action const decrement = {type: 'DECREMENT' } 復(fù)制代碼- action創(chuàng)建函數(shù),就是創(chuàng)建action的方法,只是簡單的返回一個action。 如下,定義的increment()函數(shù),返回的就是簡單的一個action,方法內(nèi)的text可以定義每次修改的數(shù)值的多少。
3、定義reducer
- reducer的職責(zé)就是根據(jù)不同的action來處理數(shù)據(jù)。根據(jù)第三條規(guī)則,使用純函數(shù)來執(zhí)行修改。
對于純函數(shù)必須遵守以下約束。
- 不得改寫傳入的參數(shù)
- 不能調(diào)用系統(tǒng)I/O的API(如DOM操作、http請求)
- 不能調(diào)用不純的方法(如Date.now()或者M(jìn)ath.random())。
對于計數(shù)器案例,定義的reducer如下,
function reducer(state = initState, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + action.text }case 'DECRMENT':return { count: state.count - 1 }default:return state} } 復(fù)制代碼需要注意
- 不能修改state,
- 在default的情況下返回舊的state
當(dāng)數(shù)據(jù)量多時需要對數(shù)據(jù)進(jìn)行拆分處理,可以定義多個reducer,然后進(jìn)行合并。
function reducer(state = state,action){return{//狀態(tài):reducer(state.狀態(tài),action),todos:todos(state.todos,action),visibility:visibility(state.todos,action)} } 復(fù)制代碼4、創(chuàng)建store,并使用
store提供了三個API接口,分別是
- getState:用于獲取狀態(tài)
- dispatch:用于派發(fā)action
- subscribe:當(dāng)狀態(tài)發(fā)生變化時執(zhí)行的回調(diào)函數(shù)
使用回調(diào)函數(shù),以及執(zhí)行函數(shù):
store.subscribe(() => {console.log(`現(xiàn)在的狀態(tài)為:${store.getState().count}`) }) store.dispatch(increment(1)) store.dispatch(increment(3)) store.dispatch(decrment()) 復(fù)制代碼react-redux
- react-redux是鏈接react與redux的專用庫。在使用時需要格外安裝。學(xué)習(xí)react-redux最主要的就是學(xué)習(xí)其中的三個一,一種開發(fā)思想,一個connect方法,以及一個provide組件。
- 1、一種開發(fā)思想:組件分離思想
react-redux提出了“智能”組件和“笨拙”組件相分離的開發(fā)思想,
- “智能”組件,即容器組件,主要特點(diǎn)有:(1)負(fù)責(zé)管理數(shù)據(jù)和業(yè)務(wù)邏輯,不負(fù)責(zé)UI的呈現(xiàn),(2)帶有內(nèi)部狀態(tài),(3)使用redux的API。
- “笨拙”組件,又稱展示組件,特點(diǎn):(1)只負(fù)責(zé)UI的呈現(xiàn), 不帶有任何的業(yè)務(wù)邏輯,(2)沒有狀態(tài),(3)所有數(shù)據(jù)由參數(shù)(this.props)提供,(4)不適用redux的API。
- 2、一個connect方法:將“笨拙”組件,變成“智能”組件。
react-redux提供了一個connect方法,用于從“笨拙”組件生成容器組件。 其中狀態(tài),是指state數(shù)據(jù),邏輯,是指修改state的方法.
- 3、一個provider組件:為后代組件提供store對象。 在使用connect方法時,用到了store對象的dispatch方法,那么此時我們就需要使用provide組件,將store傳遞過去了。
還是以counter計數(shù)器為例,但是這次使用腳手架create-react-app的方式:
//安裝腳手架create-react-app: npm i create-react-app -g //創(chuàng)建項(xiàng)目 create-react-app counter //安裝react-redux npm i redux react-redux //然后啟動項(xiàng)目 npm start 復(fù)制代碼counter案例:
1、先定義組件
//定義Show組件 export default class Show extends React.Component{render() {return (<h2>counter:{this.props.counter}</h2>)} } //定義Add組件,Sub組件與Add組件一樣 export default class Add extends Component{render() {return (<button>+</button>)} } //定義counter組件,顯示內(nèi)容 class Counter extends Component {render() {return (<div><Show/><p><Add/> <Sub/> </p></div>)} } 復(fù)制代碼2、創(chuàng)建store
- 1、定義store以及action creators
- 2、定義reducer以及合并
- 3、創(chuàng)建store
- 4、使用connect轉(zhuǎn)化組件 在使用connect時,需要先導(dǎo)入必要的方法
在導(dǎo)入必要的方法后,才能使用。
// 定義mapStarteTopProps,建立從state到props對象的映射,接受state作為參數(shù) function mapStarteTopProps(state) {return {counter: state.counter}} // 定義mapDispatchToProps,用于建立笨拙組件的參數(shù)到store.dispatch方法的映射,以dispatch為參數(shù) function mapDispatchToProps(dispatch) {return bindActionCreators(action, dispatch)} // 將Counter變成容器組件并導(dǎo)出,需要在頂層使用 provide組件,引入store,這樣在子組件內(nèi)就可以使用store了。 export default connect(mapStarteTopProps, mapDispatchToProps)(Counter) 復(fù)制代碼- 5、使用provider組件,傳遞store
- 6、在各個子組件使用方法和屬性
部分修改如下:
//在Add組件內(nèi)使用increment方法 export default class Add extends Component{render() {return (<button onClick={()=>this.props.increment()}>+</button>)} } //修改Counter組件,顯示數(shù)據(jù),以及給子組件傳遞方法 class Counter extends Component {render() {return (<div><Show counter={this.props.counter} /><p><Add increment={this.props.increment} /> <Sub decrement={this.props.decrement} /> </p></div>)} } 復(fù)制代碼- 測試如下:
在react-redux中實(shí)現(xiàn)異步操作
- 定義異步的action creator函數(shù)
在異步action中,返回一個函數(shù),在該函數(shù)中去調(diào)用同步的action即可。 這個函數(shù),會自動的獲取dispatch和getState。
//定義異步操作,在點(diǎn)擊后兩秒實(shí)現(xiàn)加操作 export function incrementAsync() {return function (dispatch, getState) {setTimeout(function () {dispatch(increment());}, 2000)} } 復(fù)制代碼- 先前已經(jīng)定義好了框架,現(xiàn)在只需在定義好的框架內(nèi),定義方法以及調(diào)用方法即可。
- redux默認(rèn)是不支持異步action的,因此我們需要使用中間件來強(qiáng)化store,讓Reducer 在異步操作結(jié)束后自動執(zhí)行。
- 使用中間件:
這樣就可以在redux內(nèi)實(shí)現(xiàn)異步操作了。
轉(zhuǎn)載于:https://juejin.im/post/5b7783b4f265da435b0b251c
總結(jié)
以上是生活随笔為你收集整理的小白路程之----初学React语法栈之redux与react-redux的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速了解和使用Photon Server
- 下一篇: logback基本入门