本文教你實現一個最簡單的 Redux 應用,以及結合 React 如何使用。react
狀態管理工具,使用以後能夠清晰的知道應用裏發生了什麼。數據如何修改,如何更新的。git
之前我剛接觸 Redux 這類狀態管理工具的時候就在想:爲何須要這些東西呢,刷新數據就消失了,也不能持久化存儲數據,有啥用呢? 後來慢慢的應用越作越多,功能越作越複雜,就會發現,不少數據什麼緣由修改的,何時修改的,本身是一臉懵逼。啥也想不起來了,維護起來真的痛苦。到了這個時候才發現 Redux 這類工具的厲害之處。名字也很應景的,狀態管理工具。說的很清楚了,就是管理狀態的。讓數據變化過程儘量的清晰、可預測。github
在項目中添加 Redux 並非必須的。請根據項目需求選擇是否引入 Reduxnpm
單一數據源 整個應用的 state 被儲存在一棵 object tree 中,而且這個 object tree 只存在於惟一一個 store 中。redux
State 是隻讀的 惟一改變 state 的方法就是觸發 action,action 是一個用於描述已發生事件的普通對象。數組
使用純函數來執行修改 爲了描述 action 如何改變 state tree ,你須要編寫 reducers。bash
Action(將要發生的操做)app
Reducer(根據 action 更新 state,是一個純函數)ide
存放 state 數據的 Store(將 action 和 reducer 聯繫到一塊兒的對象)函數
提供 getState() 方法獲取 state
提供 dispatch(action) 方法更新 state
經過 subsctibe(listener) 註冊監聽器
經過 subscribr(listener) 返回的函數註銷監聽器
說了這邊文章是教你建立一個最簡單的 Redux 應用,那咱們下面就看看使用一個 Redux 到底能有多簡單,多快呢。
使用前先引入 Redux:
npm install redux -S
先來個 Action 三要素之一不就是有 Action 麼,有咱們就先寫一個 Action 建立函數唄
Action 建立函數,是一個返回 action 的函數,非必須這樣寫,只是更方便移植和複用,建議使用 Action 建立函數來生成 action
function increment() {
return {
type: "INCREMENT"
}
}
複製代碼
有了Action,還要有 Reducer 來執行更新啊 Reducer 既然必不可少,就在寫一個 Reducer。(這裏可能會有點迷糊,reducer 不是一個對象,而是一個返回更新後 state 的純函數)
/** * counters 就是一個 reducer,根據傳入的 action 的 type 不一樣,返回一個新的 state 數據 */
// 先初始化 state
const initCounter = 0;
function counters(state = initCounter, action) {
switch(action.type) {
case 'INCREMENT':
return state ++;
default:
return state;
}
}
複製代碼
還得有一個存放 state 數據的 store 吧 如今要把咱們寫好的 Action 和 Reducer 鏈接起來
const { createStore } = require('redux');
const store = createStore(counters);
複製代碼
store.dispatch(increment());
複製代碼
查看結果
就這三步,操做完了吧,那咱們如今能夠看一下結果了
// 經過 store.getState() 獲取 State 數據
console.log('counters: ', store.getState()); // => counters: 1
複製代碼
過程總結:
建立一個操做指令 action -> 建立一個 reducer -> 經過 createStore(reducer) 建立一個 store -> 經過 store。dispatch(action) 執行 reducer 中的更新操做,更新 store 中的數據。
這些就是 Redux 的核心用法,有沒有感受很簡單的,有興趣的話能夠跟我一塊兒繼續往下,看一看結合 React 該如何使用呢。
用來組合 React 和 Redux 配合使用的插件
以 create-react-app 腳手架爲例,請先使用 create-react-app 建立一個本地項目。本例中默認 create-react-app 已全局安裝過了
$ npm npm init react-app react-redux-todos
$ cd react-redux-todos
複製代碼
$ npm install redux react-redux -S
複製代碼
在組件根目錄使用 react-redux 提供的 Prodiver 標籤包裹
import { Provider } from 'react-redux';
<Provider store={ store }> ... </Provider>
複製代碼
在須要用到 state 或 action 的組件中使用 connect 高階組件進行包裝
import { connect } from 'react-redux';
import { createAction } from './actions'
// mapStateToProps 編寫方式
const mapStateToProps = (state) => {
return {
reducer: state.reducer
}
}
// mapDispatchToProps 編寫方式
const mapDispatchToProps = (dispatch) => {
return {
createAction: text => dispatch(createAction(field));
}
}
// 使用 connect 將 state 和 dispatch 包裝到 Component 的屬性中
export default connect(mapStateToProps, mapDispatchToProps)(Component);
複製代碼
在組件中就能夠經過 this.props.reducer 和 this.props.createAction 的方式獲取數據以及調用 action 了
當有多個 reducer 時,建立 store 以前須要將它們先進行合併
import { combineReducers } from 'redux';
// 合併成一個 reducers
const reducers = combineReducers({
a: doSomethingWithA,
b: processB,
c: c
});
複製代碼
調用 store.subsctibe(listener) 註冊監聽事件 store 中的數據發生變化時,就會調用 listener 函數
/** * 經過 store.subscribe(function) 註冊一個監聽器。每次 state 更新時,都會打印輸出日誌 */
store.subscribe(() => console.log(store.getState()));
複製代碼
store.subscribe(listener) 的返回值是一個 註銷監聽的函數
/** * store.subscribe(func) 會返回一個函數,執行這個函數能夠註銷監聽器 */
// 返回一個函數 unsubscribe
const unsubscribe = store.subscribe(() => console.log(store.getState()));
// 執行這個函數能夠註銷監聽器
unsubscribe();
複製代碼
這裏有關於 Redux 最詳細的介紹和講解,我就很少此一舉了,有興趣的同窗能夠去看看哈。