Redux的工作流程


1.Redux 是一個專門用來管理數據業務或邏輯狀態的框架,它也可以實現代碼結構的規范化並提供組件之間通信的便利,而這兩點,對於大型應用來說非常關鍵。

2.工作流程:

Redux 三大原則

  • 單一數據源 整個應用的 state 被存儲在一個 Object tree 中,且只存在於唯一的Store中。

  • state 是只讀的 唯一改變 state 的方法就是觸發 action,action 是一個用於描述發生事件的普通對象,視圖部分只需要表達想要修改的意圖,所有修改都會被集中化處理。

  • 使用純函數來執行修改 為了實現根據 action 修改 state值,我們就需要編寫 Reducer。它是一個純函數,接收先前的 state 和 action 返回新的 state ,隨着應用的變大,你可以將它拆成多個小的 Reducer ,分別獨立操作 state tree 中的不同部分。

 

2.具體工作步驟

 

 

 

 

Action

const add =()=>{ return { type:"add", data:id, } }

上邊函數返回的就是一個 Action,它是一個包含 type 和 data 的對象。 Action 的作用就是告訴狀態管理器需要做什么樣的操作,正如上邊的例子,就是要添加一條信息,這樣就定義了一個Action,而 data 就是你做這個操作需要的數據。

Reducer

reducer 是一個函數(純函數),接受 舊 state 和 action,根據不同的 Action 做出不同的操作並返回新的 state 。即:(state, action) => state

const reducer = (state,action)=>{ switch(action.type){ case "add": state['newItemId'] = action.data; return {...state}; case "delete": delete state.newItemId; return {...state}; default : return state; } }

在沒有任何操作的情況下,我們返回的 state 與原 state 相同。

Store

import { createStore } from 'redux'; const store = createStore(reducer);

這就是 store, 用來管理 state 的單一對象,其中有三個方法:

  • store.getState():獲取state ,如上,經過 reducer 返回了一個新的 state,可以用該函數獲取。

  • store.dispatch(action):發出 action,用於觸發 reducer 更新 state,

  • store.subscribe(listener):監聽變化,當 state 發生變化時,就可以在這個函數的回調中監聽。

React-Redux

Redux 官方提供的 React 綁定庫。

容器組件與傻瓜組件

在應用中,通常容器組件對於 Redux 可知,他們的子組件應該是"傻瓜的"(傻瓜組件),並且通過porps獲取數據。 容器組件: 通過組件 state 屬性維護自身及其子組件的數據,它可以向 Redux 發起 action ,從 Redux 獲取 新state值。 傻瓜組件: 通過 props 調用回調函數,從 props 獲取數據展示。

注入 Store

import React from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; import { Provide } from 'react-redux'; import reducer from './reducer'; import App from './app'; const store = createStore(reducer); class RootComp extends React.Component{ render(){ //... return (//將整個視圖結構包進 Provider <Provider store={store}> <App/> </Provider> ) } } ReactDOM.render(<RootComp/> ,document.getElementById('root'));

connect#

該方法用於從 UI 組件生成容器組件,

import React from 'react'; import { connect } from 'react-redux'; import Home from './home'; class AppContainer extends React.Component{ render( return ( <Home/> ); ) } const App = connect()(AppContainer);//這里的App就是生成的容器組件。 export default App;

connect( mapStateToProps , mapDispatchToProps , mergeProps , options )();

連接 React 組件與 Redux Store

  • mapStateToProps 該參數為一個 function mapStateToProps (state,[ownProps]){...},定義該參數后組件就可以監聽 Redux Store 的變化,任何時候只要store發生變化,該函數就會被調用,該函數必須返回一個純對象,它會與組件的 props 結合,而第二個參數 ownProps 被指定時,它代表傳遞到該組件的props,且只要組件收到新的 props ,mapStateToProps 就被調用。

  • mapDispatchToProps 通常我們會將該參數省略,此時默認情況下,dispatch 會注入到組件的props中,在你需要出發 action 的地方(可能是某個事件函數)使用該disaptch 函數將 action 發出。

例子:

在上邊例子中,我們只要點擊下添加鏈接,組件就會通過點擊事件觸發 dispath 函數 發送 action 到 store 中的 reducer, reducer 則根據 action 的 type 來決定執行什么操作,之后在 store 中新增一條記錄(newItemId)后返回一個新的 state (里邊包含Store中發生改變后的所有值),由於組件使用 connect 將自己與 Store 綁定起來,Store 中的值發生變化就會執行 mapStateToProps,將新的 state 放入組件的 props,從而引發組件的渲染。

 

3. 異步中間件

也許你也已經發現了前邊的介紹中有個關鍵的問題沒解決,那就是異步操作(最典型的就是通過ajax訪問后台數據)。Action 發出以后,Reducer 立即計算出 State,這叫同步Action 發出之后,過段時間再執行 Reducer,這就是異步。 如和何才能讓 Reducer 在異步操作結束后自動執行呢?這就需要異步中間件來解決。

 

中間件通過對 store.dispatch 進行改造,在發出 Action 和執行 Reducer 這兩步之間添加其他功能。 中間件可以做很多事情,這里主要講解異步中間件redux-promise-middleware的使用。

//Store.js 加載中間件 import { applyMiddleware,createStore } from 'redux'; import createPromiseMiddleware from 'redux-promise-middleware'; import reducer from './reducers/index'; const store = createStore({//createStore 可以接受應用初始狀態作為參數,這時, `applyMiddleware` 就是第三個參數。 reduer, applyMiddleware([createPromiseMiddleware()]) }); export default store;

 

發起異步action#

//actions.js export const getTodos = () => { const apiUrl = `/todos`; return { type: GET_TODO, //屬性 payload 值為 Promise 類型(中間件據此判斷是否需要異步處理) payload: fetch(apiUrl).then(response => { if (!response.ok) { //請求返回的可能是500等錯誤,也會執行到這里,需將狀態設置為 rejected return Promise.reject(response.status); } return response.json(); }) }; }

處理異步 actions#

一般 action 的處理,發起和處理是一一對應的,而異步 action 則有三個 action 來處理,分別對應異步的三種狀態

  • ${GET_TODO}_PENDING 異步請求執行后會立刻 dispatch 此 action,表示請求已發出,正在等待返回值

  • ${GET_TODO}_FULFILLED 異步請求成功后會 dispatch 此 action,注意 Response 只要回來,即使是 500,也會執行到這里

  • ${GET_TODO}_REJECTED 異步請求失敗后會 dispatch 此 action

上述三個 action 及后綴皆為中間件redux-promise-middleware的約定,不同中間件約定可能不一致。

//reducer.js case `${GET_TODO}_PENDING`: { return { status: FetchStatus.LOADING, } } case `${GET_TODO}_FULFILLED`: { return {status: FetchStatus.SUCCESS, items: action.payload}; } case `${GET_TODO}_REJECTED`: { return {status: FetchStatus.FAILURE, error: action.payload}; }



 


免責聲明!

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



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