堅持造輪子第四天 - 統一狀態管理

堅持造輪子第四天 - 統一狀態管理

二話不說 輪子我都會造 還怕你面試問嗎? 一天造一個輪子,幹就完了。前端

看點

  • 針對大廠筆試、面試必考手寫題目
  • TDD方式開發
  • 配合視頻講解

造輪子計劃

(計劃趕不上變化 隨時迭代 歡迎留言 隨時摸魚)git

  • 框架基礎
  • JS基礎
    • Promise.all/race
    • 路由
    • new
    • call/apply/bind
    • Object.create
    • 深拷貝、淺拷貝
  • 算法、設計模式
    • 二分查找
    • 快排
    • 二分查找
    • 冒泡排序
    • 選擇排序
    • 訂閱發佈
    • 斐波那契算法
    • 去重

統一狀態管理

若是編寫一個複雜的前端程序,不太可能讓組件各自爲政。狀態和行爲邏輯都分散在各自組件內部,很難統一管理,那也就很難作大.好比: 你們想一想作一個在線版的Excel或者PS 又或者後面咱們要寫的VSCode應該怎麼作?裏面的各類組件互動,Undo、Redo、行爲記錄怎麼作?在線版王者榮耀如何播放視頻錄像,如何直播?github

要完成這樣的功能須要三個要求:面試

  • 單一數據源 : 就是狀態數據統一放在一塊兒算法

  • 保持狀態只讀 : 狀態數據誰都不能改,須要改的話找管理員贊成修改設計模式

  • 數據修改使用純函數 : 修改數據的方法也要統一管理,這樣容易回退,記錄復現、時間旅行markdown

  • 狀態通知 : 狀態修改能夠獲得通知,固然不少人都要收聽這個最好使用訂閱發佈模式。這個不是剛需,我就一個地方用用怎麼了。誰變了我整個視圖都刷新。因此我們拆解開,此次只知足能觸發狀態變動通知就好了。後面設計模式我們在慢慢盤這些東西。app

需求

1. 經過dispatch修改狀態

2. 狀態變動後觸發通知

it("基本功能 訂閱通知 改變狀態", () => {
    const { createStore } = require("../index");
    const mockFn = jest.fn();
    const store = createStore(reducer);

    // 創建響應訂閱
    store.effect(mockFn);
    store.dispatch({
      type: "clear",
    });
    // store.dispatch({ type: "add", payload: 1 });

    const calls = mockFn.mock.calls;

    // 斷言 mock方法只調用一次
    expect(calls.length).toBe(1);
    expect(store.getState().num).toBe(0);
  });
複製代碼

功能實現

超級簡單是吧 我就解釋了框架

module.exports.createStore = (reducer, preloadedState) => {
  let currentReducer = reducer; //reducer函數
  let currentState = preloadedState; //默認state
  let effective 
  return {
    getState() {
      return currentState;
    },
    dispatch(action) {
        currentState = currentReducer(currentState, action);
        // 觸發通知
        effective()
    },
    effect(fn) {
        effective = fn;
    },
  };
};

複製代碼

測試

OK 任務完成異步

遺留問題 - 後續解決

主要是咱們拆解了和統一狀態管理不強綁定的問題。

1. 變動通知訂閱

固然這個實現訂閱發佈模式就好了

2. 異步Action的處理

大概兩個方案Thunk方案 和 Promise方案 這個等咱們後續分別造完Thunk和 Promise輪子再說

3. 狀態日誌

這個須要引入中間件洋蔥圈模型也就是實現責任鏈模式

4. 和時間旅行

這個須要實現備忘錄設計模式

關注全棧然叔 帶你堅持每天造輪子 (週末休息 拒絕996)

相關文章
相關標籤/搜索