pcwu's TIL Notes


[Redux] Redux store 介紹

Store

Redux 的 store 主要就是所謂的 store tree,集中管理了整個 app 的狀態資訊。整個 Redux 就是以 store 為核心來運作,所以 store 只會且只能有一個,而且所有東西都會被包在裡面(reducermiddleware等等)

引入 createStore

createStore 顧名思義就是拿來建立 store 的玩意兒。以下三種方法都可以建立 createStore,端看你是用哪種方式引進 redux 的:

const { createStore } = Redux; // ES 6 include redux.js in HTML
var createStore = Redux.createStore; // ES 5 include redux.js in HTML
import { createStore } from 'redux'; // with webpack and babel

建立 store

store 需包含 reducer,如此才知道在發生某些 action 時,該怎麼做動得到目前該有的狀態(state)。所以將 reducer 引入 createStore 後,即可建立 store

const store = createStore(reducers);

store 的方法

store 有以下三個最主要的方法:

所以如果自己寫一個 createStore 的話,大概是長這樣:

const createStore = (reducer) => {
  let state;
  let listeners = [];

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    };
  };

  dispatch({}); // to initial state

  return { getState, dispatch, subscribe };
};

這邊需要特別強調的是,dispatch 在核心概念中,是唯一可以改變 state 的方法。一開始會先 dispatch({}) 讓 state 獲得初始值。

Store 應用例子

以計數器為例子:

const { createStore } = Redux;
// var createStore = Redux.createStore;
// import { createStore } from 'redux';

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

// create a store
const store = createStore(counter);
console.log(store.getState());  // 0

// dispatch an action
store.dispatch({ type: 'INCREMENT' });
console.log(store.getState());  // 1

// subscribe a callback function
store.subscribe(() => {
  document.body.innerText = store.getState();
});

// dispatch an action due to event(click)
document.addEventListener('click', () => {
  store.dispatch({ type: 'INCREMENT' });
});

Reference and Reading