入口文件
import createStore from "./createStore";
import combineReducer from "./combineReducer";
import bindActionCreator from "./bindActionCreator";
export {
createStore,
combineReducer,
bindActionCreator
}
createStore.js
创建仓库的方法 传入 reducer 和 初始state(可不传)
export default function (reducer, initState) {
//初始化state
initState = initState ? initState : null;
function getState() {
return initState;
}
let listeners = [];
function dispatch(action) {
if(!isPlainObject(action)){
throw new Error('action必须是一个纯对象');
}
if(!action.hasOwnProperty("type")) {
throw new Error('action必须有type属性');
}
// 更新state
initState = reducer(initState, action);
// 执行listener
for(var i = 0; i < listeners.length; i++) {
listeners[i]()
}
}
// 订阅 listener 是更新的setState
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {// 返回一个销毁的操作
let index = listeners.indexof(listener)
list.splice(index, 1)
}
}
// 初始化执行一下dispatch 拿到 state 因为默认走的是 default
dispatch({type: "@@redux/INIT"})
return {
dispatch, getState, subscribe
}
}
export default function isPlainObject(obj){
if(typeof obj != 'object' || obj === null){
return false;
}
return Object.getPrototypeOf(obj) === Object.prototype;
}
combineReducers.js
export default function (reducers) {
let keys = Object.keys(reducers); // 获取合并reducers 的keys {num1, num2}
return function (state, action) {
let currentState = {};
for(let i = 0; i < keys.length; i++) {
let item = keys[i]; // num1 || num2
let reducer = reducers[item]; // 合并其中一项reducer
let previousState = state[item]; // 上一个状态的值
let nextState = reducer(previousState, action); // 下一个状态值
currentState[item] = nextState; // 返回当前key的state
}
return currentState;
}
}
bindActionCreators.js
用来自动
dispatch action; 这个方法会返回一个对象; 直接import bindActionCreators from './bindActionCreators'进行调用acion对象中的方法即可,就可以直接派发action,不用再次调用dispatch; egg:bindActionCreators.add
function bindActionCreator(action, dispatch) {
return function () {
dispatch(action.apply(this, arguments))
}
}
export default function (actions, dispatch) {
return function () {
if (typeof actions === "funtion") {
return bindActionCreator(actionCreators, dispatch);
} else {
let actionCreators = {};
for (let key in actions) {
actionCreators[key] = bindActionCreator(actions[key], dispatch);
}
return actionCreators;
}
}
}