理解 Redux 原始碼(一)- 前言及基本知識

  這是小弟第一次撰寫原始碼相關的文章,其實看自己使用工具的原始碼其實也不是第一次,在實務上了解某個 API 底層運作也能對工具更加熟悉,但真正完整看完整個專案的經驗還真的沒有過,而選擇 Redux 的原因也是某次打開原始碼才發現哇賽,本以為很複雜的東西原始碼並沒有想像的那麼多,於是就花點時間看完並記錄一下。

  Redux 是用來解決狀態多層傳遞造成的難以管理問題,Redux 是其中一個解法但不是唯一解,也可根據專案需求評估要不要使用它,但這裡並不討論使用的場景,單純針對它的原始碼進行探討。

最好必須先知道…

  而在真正深入以前得先了解每個 API 的作用,雖然直接看程式碼理解也可以但非常不建議,有個脈絡整個讀下來會更有頭緒,會看這篇文章的你想必已經對 Redux 有一定的了解,不過這邊還是先稍微帶過主要的概念,先上一張 Redux 官方的示意動畫。

https://d33wubrfki0l68.cloudfront.net/01cc198232551a7e180f4e9e327b5ab22d9d14e7/b33f4/assets/images/reduxdataflowdiagram-49fa8c3968371d9ef6f2a1486bd40a26.gif



核心觀念大概是:
  1. 建立 store,store 包含你需要的 global state 以及其他 redux 的 api 像是 dispatch, subscribe 等等。
  2. 唯一改變 state 的方式是呼叫 store.dispatch 方法,通常會在使用者事件下觸發,例如點擊「存錢」將 state 內的存款更新。
  3. dispatch 接受一個 action 做為參數,而 action 則是描述目前行為細節的物件,格式像這樣:
{ type: 'DEPOSIT', payload: 10 }

  而在建立 store 時會傳入一個 reducer function,這時 reducer function 會依據目前的狀態及 action 的內容來判斷要怎麼更新 state

  1. state 更新後重新渲染 UI

  這是一個很簡易的大綱,而第四點重新渲染 UI 的部分事實上也並不在 Redux 內執行,而是要配合其他套件像是 React-Redux 來實現,不過這邊主要重點還是會放在 Redux,有時間可以再來聊聊 React-Redux。


補充

  最後分享一下 Dan 大大在他這篇文章 You Might Not Need Redux 裡寫的用 React 模擬 Redux 的行為,描寫的部分包括 action 的格式、reducer 如何藉由 action 判斷要返回的新 state,以及 dispatch 扮演的角色,對於理解 reducer, dispatch, action 整個交互運作非常有幫助。

import React, { Component } from 'react';

// reducer
const counter = (state = { value: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + 1 };
case 'DECREMENT':
return { value: state.value - 1 };
default:
return state;
}
}

class Counter extends Component {
state = counter(undefined, {});

dispatch(action) {
this.setState(prevState => counter(prevState, action));
}

increment = () => {
this.dispatch({ type: 'INCREMENT' });
};

decrement = () => {
this.dispatch({ type: 'DECREMENT' });
};

render() {
return (
<div>
{this.state.value}
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}


參考文獻

Redux 官方文件