redux--初步

89 阅读2分钟

createStore

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

  function getState() {
    return state;
  }

  function subscribe(callback) {
    listeners.push(callback);
  }

  // reducer 修改 state,接收参数action
  function dispatch(action) {
    state = reducer(state, action);
    for (let i = 0; i < listeners.length; i++) {
      listeners[i]();
    }
  }

  let store = {
    getState,
    subscribe,
    dispatch,
  };

  // 初始化 state
  state = reducer(state, { type: Redux.INIT });

  return store;
}

window.Redux = {};
Redux.createStore = createStore;

测试代码

const initState = {
  count: 0,
};

function reducer(state = initState, action) {
  switch (action.type) {
    case "ADD":
      return { ...state, count: state.count + action.count };
    case "SUB":
      return { ...state, count: state.count - action.count };
    default:
      return state;
  }
}

let store = createStore(reducer);

store.subscribe(() => console.log(store.getState()));

store.dispatch({ type: "ADD", count: 1 });

combineReducers

function combineReducers(reducers) {
  const keys = Object.keys(reducers);

  const reducer = function (state = {}, action) {
    const nextState = {};

    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      nextState[key] = reducers[key](state[key], action);
    }

    return nextState;
  };
  return reducer;
}

测试代码

function todosReducer(state = [], action) {
  switch (action.type) {
    case "ADD_Todo":
      return [...state, action.todo];
    default:
      return state;
  }
}

function couterReducer(state = 0, action) {
  switch (action.type) {
    case "ADD":
      return state + action.count;
    case "SUB":
      return state - action.count;
    default:
      return state;
  }
}

let reducer = combineReducers({
  todos: todosReducer,
  count: couterReducer,
});

let store = createStore(reducer);

console.log(store.getState());

redux 中间件系统 -- applyMiddleware

function combineReducers(reducers) {
  const keys = Object.keys(reducers);

  const reducer = function (state = {}, action) {
    const nextState = {};

    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      nextState[key] = reducers[key](state[key], action);
    }

    return nextState;
  };
  return reducer;
}

// 中间件
function applyMiddleware(middleware) {
  // 返回一个函数,这个函数接收createStore,返回新的createStore
  function enhancer(createStore) {
    // 返回新的createStore 接收reducer 返回新的store
    function newcreateStore(reducer) {
      const store = createStore(reducer);

      const func = middleware(store);

      const { dispatch } = store;
      // 返回新的dispatch
      const newDispatch = func(dispatch);
      return { ...store, dispatch: newDispatch };
    }
    return newcreateStore;
  }

  return enhancer;
}

// 第二个参数是中间件,可以做日志记录,性能分析,异常处理等
function createStore(reducer, enhancer) {
  if (enhancer && typeof enhancer === "function") {
    // 返回新的createStore
    const newcreateStore = enhancer(createStore);

    const newStore = newcreateStore(reducer);

    return newStore;
  }

  let state;
  let listeners = [];

  function getState() {
    return state;
  }

  function subscribe(callback) {
    listeners.push(callback);
  }

  // reducer 修改 state,接收参数action
  function dispatch(action) {
    state = reducer(state, action);
    for (let i = 0; i < listeners.length; i++) {
      listeners[i]();
    }
  }

  let store = {
    getState,
    subscribe,
    dispatch,
  };

  // 初始化 state
  state = reducer(state, { type: Redux.INIT });

  return store;
}

window.Redux = {};
Redux.createStore = createStore;
Redux.combineReducers = combineReducers;
Redux.applyMiddleware = applyMiddleware;

测试代码

// const { createStore, combineReducers, applyMiddleware } = Redux;
const initState = {
  count: 0,
};

// function reducer(state = initState, action) {
//   switch (action.type) {
//     case "ADD":
//       return { ...state, count: state.count + action.count };
//     case "SUB":
//       return { ...state, count: state.count - action.count };
//     default:
//       return state;
//   }
// }

function todosReducer(state = [], action) {
  switch (action.type) {
    case "ADD_Todo":
      return [...state, action.todo];
    default:
      return state;
  }
}

function couterReducer(state = 0, action) {
  switch (action.type) {
    case "ADD":
      return state + action.count;
    case "SUB":
      return state - action.count;
    default:
      return state;
  }
}

let reducer = combineReducers({
  todos: todosReducer,
  count: couterReducer,
});

function logger(store) {
  return function (dispatch) {
    return function (action) {
      console.log("beforeDispatching", action);
      let result = dispatch(action);
      console.log("After Dispatch next state", store.getState());
      return result;
    };
  };
}

let store = createStore(reducer, applyMiddleware(logger));

store.dispatch({ type: "ADD_Todo", todo: "hello" });
console.log(store.getState());

// store.subscribe(() => console.log(store.getState()));

// store.dispatch({ type: "ADD", count: 1 });