redux原理

sbwxffnhc發表於2019-01-07

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工作流程:

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();

複製程式碼

相關文章