npm install --save redux
Redux是將整個應用狀態儲存到一個地方,稱為store,裡面儲存一棵狀態樹state tree。元件可以派發(dispatch)行為(action)給store,而不是直接通知其它元件。元件內部通過訂閱store中的狀態(state)來重新整理自己的檢視。
subscribe 這個函式是用來去訂閱 store 的變化,比如你每次對 store 進行 dispatch(action)都會觸發 subscribe 註冊的函式呼叫,這個在實際情況不是必須要的,看自己的應用場景,比如你想監控 store 的全域性變化時 可以用 subscript 訂閱一下,然後作一些反應
複製程式碼
下圖是非redux方式和redux方式:
redux工作流程:
圖解:
redux
dispatch 傳送命令
action dispatch傳送的命令action
reducer 處理器,處理action ,改變state >------store
state ,被reducer處理器的action命令改變
例:
元件1:傳送命令,dispatch---action:{type:'changeColor',color:'red'}
處理器收到action後改變state
其他元件根據state重新整理自己
複製程式碼
redux實現步驟:
1 建立倉庫,儲存state 和 reducer 獲取最新狀態 向倉庫傳送action 訂閱倉庫內的狀態變化(訂閱完成後取消訂閱)
一個簡單的例子:
//redux.js 封裝的redux庫
/**
* redux跟react並沒必然的關係
* createStore 建立倉庫
**/
//let {createStore} = require('redux');
let createStore = (reducer) => {
let state;//定義初始狀態
let getState = () => state;//用來獲取最新的狀態
let listeners = [];//監聽函式陣列
//向倉庫發關action
let dispatch = (action) => {
//傳入老狀態和本次的action,返回新狀態
state = reducer(state,action);
//通知所有的監聽者,讓所有的監聽函式依次執行
//依次呼叫所有的訂閱函式
listeners.forEach(listener=>listeners());
}
//訂閱倉庫內的狀態變化事件,當狀態發生變化後會監聽函式
//訂閱方法執行後會返回一個取消訂閱的函式,呼叫它訂閱
let subscribe = listener =>{
listeners.push(listener);
//訂閱方法執行後會返回一個取消訂閱的函式,呼叫它訂閱
return ()=>{
listeners = listeners.filter(l=>listener!==l);
}
}
//在建立倉庫的時候就直接派發一次空的action,確保state有初始值
dispatch({});
return {
getState, //獲取最新的狀態物件
subscribe, //原來訂閱狀態變化事件
dispatch //發身action
}
}
export {createStore}
複製程式碼
//index.js
import {createStore} from './1.redux'
import $ from 'jquery'
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE'
$('#body').append(`
<p id="counter"></p>
<button id="increaseBtn">+</button>
<button id="decreaseBtn">-</button>
`);
//state是狀態樹,可以是任意的結構
//action是一個純物件{type:'INCREASE',amount:2} {type:'DECREASE'}
let reducer = (state = {number:0},action)=>{
if(action === undefined) return state;
switch(action.type){
case INCREASE:
return {number:state.number+action.amount};
case DECREASE:
return {number:state.number-action.amount};
default:
return state;
}
}
//呼叫倉庫
let store = createStore(reducer);
console.log(store.getState());//undefined 需要執行一次dispatch
let render = ()=>{
$('#counter').html = store.getState().number;
}
//當倉庫裡的state發生變化的時候,會重新執行render,讀取最新的狀態資料並更新檢視
//訂閱
store.subscribe(render);
//點選函式的時候,發身一個INCREASE的action,會得到一個新的state,
$('#increaseBtn').click(()=>store.dispatch({type:INCREASE,amount:3}));
$('#decreaseBtn').click(()=>store.dispatch({type:DECREASE,amount:2}));
render();
複製程式碼