實現一個簡單的Redux

實現一個簡單的Redux

狀態管理是當前前端框架開發當中一個很重要的點

當業務或者系統複雜時,狀態管理能讓咱們更加清晰地瞭解數據的流動javascript

本文經過實現一個簡單的Redux來闡述一個狀態管理庫的思想前端

什麼是狀態管理,咱們爲何須要狀態管理

目前前端開發框架盛行,在框架的使用過程當中就會遇到一個問題:組件間的數據通訊如何來作。簡單是父子組件咱們能夠經過props來實現數據通訊,當組件層級變深,僅靠props就不足夠支撐咱們的需求,一個全局的狀態管理也就變爲一個迫切的需求。java

Redux的思想

  1. Store

    Redux只有一個Store,Store不能直接進行修改,每次操做以後都是返回一個新的對象數組

  2. Action前端框架

    Action就是View發出的通知,告訴Store 數據要改變,Action經過特定的type來知曉作何種操做閉包

    const action = {
      type: 'plus',
      data: {}
    };
  3. Reducer

    Reducer是一個純函數,接受action和state,而後返回一個新的state。框架

總結一下,Redux的流程以下:函數

// View 發出 Action
store.dispatch(action);

// store 自動調用 Reducer,而且傳入兩個參數:當前 State 和收到的 Action。 Reducer 會返回新的 State
let nextState = xxxReducer(previousState, action);

// State 一旦有變化,Store 就會調用監聽函數
store.subscribe(listener);

// listener中能夠修改組件的狀態,從新渲染組件
function listerner() {
  let newState = store.getState();
  component.setState(newState);   
}

實現一個簡單的Redux

狀態管理,說到底就是將須要共享的數據存放在一個公共的地方,全部組件都經過它來進行數據的操做。天然而然的,咱們能夠想到建立一個全局的對象來存放數據,因此先建立一個state.js文件測試

// state.js
export const state = {
    count: 0,
}

有了數據,咱們就須要有數據的存取,以及發佈訂閱事件spa

所以有了如下的store.js文件

// store.js
import { state } from './state.js';
export const createStore = (reducer) => {
  let currentState = state;  // state

  function getState() {  // 獲取state
    return currentState;
  }

  function dispatch() {  // 設置state
  }

  function subscribe() {  // 訂閱事件
  }

  return { getState, dispatch, subscribe };
}

在這裏其實用到了閉包的思想

其中getState很簡單,就是獲取當前的state

dispatch

狀態管理庫的一個原則是不能隨便修改狀態的值,須要作到有條理,有標記地修改。咱們將操做單獨封裝在reducer.js中,以此來保持store.js的純淨

// reducer.js
import { state as initialState } from './state.js';
export function reducer(state = initialState, action) {
  switch(action.type) {
    case 'plus':
      return {
        ...state,
        count: state.count + 1
      };
      break;
    case 'subtract':
      return {
                ...state,
        count: state.count - 1
      }
    break;
    default:
      return initialState;
  }
}

而後在store.js中進行使用

// store.js
import { state } from './state.js';
export const createStore = (reducer) => {
  let currentState = state;  // state

  function getState() {  // 獲取state
    return currentState;
  }

  function dispatch(action) {  // 設置state
    currentState = reducer(currentState, action);
  }

  function subscribe() {  // 訂閱事件
  }

  return { getState, dispatch, subscribe };
}

狀態管理庫的另外一個能力就是可以經過數據改變引發視圖的改變。咱們經過發佈訂閱模式,就能實現這一效果,經過subscribe()來訂閱事件,在dispatch()的時候觸發訂閱的消息。固然真正的狀態管理庫中這一塊確定是很複雜的,咱們這裏只是簡單地寫個示例。

咱們經過一個數組來存放監聽的事件,經過subscribe來添加事件

// store.js
import { state } from './state.js';
export const createStore = (reducer) => {
  let currentState = state;  // state
    let queue = [];
  
  function getState() {  // 獲取state
    return currentState;
  }

  function dispatch(action) {  // 設置state
    currentState = reducer(currentState, action);
    queue.forEach(fn => {
      fn();
    })
  }

  function subscribe(fn) {  // 訂閱事件
    queue.push(fn);
  }

  return { getState, dispatch, subscribe };
}

以後添加測試用例來進行測試

import 'createStore' from './store';

const store = createStore(reducer);
store.subscribe(() => { console.log('component 1') });
store.subscribe(() => { console.log('component 2') });
store.dispatch({ type: 'plus' });
store.dispatch({ type: 'plus' });
console.log(store.getState());

// component 1
// component 2
// component 1
// component 2
// { count: 2 }

這就是一個簡單的Redux的思想。

相關文章
相關標籤/搜索