[Redux] Redux API 筆記
Top Level Exports
createStore
createStore(reducer, [preloadedState], [enhancer])
store.getState()
:取得當前所有存在 state 的內容。store.dispatch(action)
:dispatch 的 action 會傳送到 reducer,是唯一用來改變 state 的方式。store.subscribe(listener)
:在每次 action 被 dispatch 的時候都會呼叫這個 listener。store.replaceReducer(nextReducer)
:
import { createStore } from 'redux';
import rootReducer from './reducers';
// createStore
const store = createStore(rootReducer);
store.getState(); // 取得當前所有存在 state 的內容。
// dispatch action
store.dispatch({
type: 'INCREMENT',
payload: 0,
});
// subscribe(listener):每次 action dispatch 時都會呼叫到這個 callback listener
store.subscribe(() => {
document.body.innerText = store.getState();
});
createStore @ Redux API
原始碼結構
const createStore = (reducer) => {
let state;
let listeners = [];
const getState = () => state;
const dispatch = (action) => {
state = reducer(state, action); // 重要!!
listeners.forEach((l) => l());
};
const subscribe = (listener) => {
listeners.push(listener);
return () => {
listeners = listeners.filter((l) => l !== listener);
};
};
dispatch({});
return { getState, dispatch, subscribe };
};
combineReducer
combineReducers(reducers)
import { combineReducers } from 'redux';
const todoApp = combineReducers({
visibilityFilter,
todos,
});
combineReducer @ Redux API
實際上 combineReducers
是另一個 reducer,而這個 reducer 包了其他原本的 reducers,所以寫成下面這樣是一樣的效果:
/**
* combineReducer 的效果和下面的寫法一樣
* visibilityFilterReducer, todosReducer 都是 reducers
**/
const todoApp = function (state = {}, action) {
const { visibilityFilter, todos } = state;
return {
// 一旦 dispatch() 後,這裡面有寫到的 reducers 都會被呼叫到
visibilityFilter: visibilityFilterReducer(visibilityFilter, action),
todos: todosReducer(todos, action),
};
};
當 store.dispatch()
時,會執行 createStore(<combineReducers>)
時代入的 reducer,在 combineReducers
中,又會去呼叫所有在裡面有寫到的其他 reducers,因此所有的 reducers 都能接到 dispatch 的這個 action
。
也就是說,下面這兩種寫法是一樣的:
// 使用 combineReducers
const reducer = combineReducers({
a: doSomethingWithA, // A Reducer
b: processB, // B Reducer
c: calculateC, // C Reducer
});
// 沒使用 combineReducer
function reducer(state = {}, action) {
const { a, b, c } = state;
return {
a: doSomethingWithA(a, action),
b: processB(b, action),
c: calculateC(c, action),
};
}
bindActionCreators
bindActionCreators(actionCreators, dispatch)
原本需要 dispatch(action)
,但透過 bindActionCreator
後,會變成把 dispatch()
包在原本的 action
中,因此可以直接呼叫該 action 就會發出 dispatch。