直接使用 createStore:
import { createStore } from 'redux';
const counter = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
const store = createStore(counter);
console.log(`initial state : ${store.getState()}`);
store.subscribe(() => {
document.body.innerHTML = store.getState();
})
document.addEventListener('click', () => {
store.dispatch({ type: 'INCREMENT' });
});
現在 counter 方法直接沿用,另外建立一個 createStore 方法:
const createStore = (reducer) => {
// 這個 store 持有 state 變數
let state;
const getState = () => state;
const dispatch = (action) => {
};
const subscribe = (listener) => {
};
// 回傳的物件被稱為 Redux store
return { getState, dispatch, subscribe }
};
因為 subscribe() 可以被呼叫很多次,所以需要紀錄這些 listener:
let listeners = [];
const subscribe = (listener) => {
listeners.push(listener)
};
dispatch() 是唯一可以改變內部 state 的:
const dispatch = (action) => {
// 使用當前的 state 和 被 dispatch 的 action 物件當參數呼叫 reducer 計算出新的 state
state = reducer(state, action);
// 執行 listeners
listeners.forEach((listener) => { listener() });
};
還沒有實作 unsubscribe() 方法,先使用替代方案,在subscribe() 寫一個回傳一個方法:
// 回傳一個方法
// 使用方式:
// var s1 = store.subscribe(()=>{});
// s1(); // unsubscribe
return () => {
listeners = listeners.filter(l => l !== listener);
}
最後在 createStore() 回傳前加入 dispatch({});
為了得到初始 state
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({});
return { getState, dispatch, subscribe }
};
沒有留言:
張貼留言