/re0-redux

从零开始实现redux

Primary LanguageJavaScript

marp
true

从零开始实现 redux

大齐


零 · 开发环境搭建


mkdir re0-redux
cd re0-redux
yarn init
yarn add -D webpack webpack-cli
mkdir src
echo 'console.log("init");' > ./src/index.js
code .
webpack && node ./dist/main

第一步实现

  • createStore(reducer)
  • store.dispatch(action)
  • store.getState()

import { createStore } from "./re0-redux";

function reducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const store = createStore(reducer);

console.log(store.getState()); // 0

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

store.dispatch({ type: "DECREMENT" });
console.log(store.getState()); // 0

第二步实现

  • createStore(reducer, preloadedState)
  • store.subscribe(listener)
  • store.replaceReducer(nextReducer)

import { createStore } from "./re0-redux";

function reducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

function nextReducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 100;
    case "DECREMENT":
      return state - 100;
    default:
      return state;
  }
}

const store = createStore(reducer, 100);

store.subscribe(function() {
  console.log(store.getState());
});

store.dispatch({ type: "INCREMENT" }); // 101
store.dispatch({ type: "DECREMENT" }); // 100

store.replaceReducer(nextReducer);

store.dispatch({ type: "INCREMENT" }); // 200
store.dispatch({ type: "DECREMENT" }); // 100

第三步实现

  • enhancer: logger
  • compose

import { createStore, compose } from "./re0-redux";
import logger from "./enhancer/logger";
import logger2 from "./enhancer/logger2";

function reducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const createStoreWithEnhancer = compose(
  logger2,
  logger
)(createStore);

const store = createStoreWithEnhancer(reducer, 100);

store.dispatch({ type: "INCREMENT" }); // 101
store.dispatch({ type: "DECREMENT" }); // 100

第四步实现

  • applyMiddleware
  • middleware: logger

import { createStore, compose, applyMiddleware } from "./re0-redux";
import loggerMiddleware from "./middleware/logger";
import loggerMiddleware2 from "./middleware/logger2";

function reducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const createStoreWithMiddleware = applyMiddleware(
  loggerMiddleware,
  loggerMiddleware2
)(createStore);

const store = createStoreWithMiddleware(reducer, 100);

store.dispatch({ type: "INCREMENT" }); // 101
store.dispatch({ type: "DECREMENT" }); // 100

第五步实现

  • createStore(reducer, preloadedState, enhancer)

import { createStore, compose, applyMiddleware } from "./re0-redux";
import loggerEnhancer from "./enhancer/logger";
import loggerEnhancer2 from "./enhancer/logger2";
import loggerMiddleware from "./middleware/logger";
import loggerMiddleware2 from "./middleware/logger2";

function reducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

const finalEnhancer = compose(
  applyMiddleware(loggerMiddleware, loggerMiddleware2),
  loggerEnhancer,
  loggerEnhancer2
);

const store = createStore(reducer, 100, finalEnhancer);

store.dispatch({ type: "INCREMENT" }); // 101
store.dispatch({ type: "DECREMENT" }); // 100

感谢

源码:https://github.com/daqi/re0-redux
redux源码:https://github.com/reduxjs/redux/tree/9c8e440964