redux 使用redux-thunk把switch从代码里踢出去

redux 使用redux-thunk把switch从代码里踢出去

一些插件介绍

https://www.cnblogs.com/vvjiang/p/9505646.html

 

主要思想是将所有的有效修改进行合并

 

使用redux-thunk插件主要是为了能够支持异步, 以及可以传入函数

thunk的源码, 支持传入函数

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === "function") {
      return action(dispatch, getState, extraArgument);
    }
    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

 

优点是不需要各种switch了, 使用起来会简单不少, 但是过于灵活也使得不小心就会出现一些bug… 比如一般而言可以在switch分action写log, 查错也简单, 但是这种方式就是直接合并对象, 增加了调试成本….

 

import React, { useState } from "react";
import { createStore, applyMiddleware } from "redux";
import { Provider, useSelector, useDispatch } from "react-redux";
import km from "keymirror";
import * as R from "ramda";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
const ACTION_TYPES = km({
  INC_A: null,
  DEC_A: null,
  INC_B: null,
  DEC_B: null,
});

const initState = {
  A: { count: 1 },
  B: { count: 2 },
};

const reducerCreater = (actionTypes, initState) => (
  state = initState,
  { type, pyload }
) => {
  console.log("type", type, pyload, state);
  if (pyload && type in actionTypes) {
    return R.mergeRight(state, pyload);
  }
  return state;
};

const reducer = reducerCreater(ACTION_TYPES, initState);
const configStore = (preloadStore) => {
  const middlewares = [thunk.withExtraArgument({})];
  const middlewareEnhancers = applyMiddleware(...middlewares);
  const enhancers = [middlewareEnhancers];

  const composedEnhances = composeWithDevTools(...enhancers);
  const store = createStore(reducer, preloadStore, composedEnhances);

  return store;
};
const store = configStore();

const incA = (dx = 1) => (dispatch, getState) => {
  const A = R.path(["A"], getState());
  let aLens = R.lensPath(["count"]);
  let newA = R.over(aLens, R.add(dx), A);
  dispatch({
    type: ACTION_TYPES.INC_A,
    pyload: { A: newA },
  });
};
const incB = (dx = 1) => (dispatch, getState) => {
  const bLens = R.lensPath(["B", "count"]);
  let newState = R.over(bLens, R.add(dx), getState());
  dispatch({
    type: ACTION_TYPES.INC_B,
    pyload: newState,
  });
};
const Counter = () => {
  const dispatch = useDispatch();
  const [dx, setDx] = useState(1);
  const addA = () => {
    dispatch(incA(dx));
  };
  const addB = () => {
    dispatch(incB(dx));
  };

  const countA = useSelector(R.path(["A", "count"]));
  const countB = useSelector(R.path(["B", "count"]));

  return (
    <div>
      <input
        value={dx}
        type="number"
        onChange={(el) => setDx(Number(el.target.value))}
      />
      <div>
        countA:{countA}, countB:{countB}
      </div>
      <button onClick={addA}>addA</button>
      <button onClick={addB}>addB</button>
    </div>
  );
};
export default () => {
  return (
    <Provider store={store}>
      <Counter></Counter>
    </Provider>
  );
};

 

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » redux 使用redux-thunk把switch从代码里踢出去