redux中间件的使用

redux-thunk

功能: 使用中间件可以在action中返回函数,可以用来处理ajax异步请求

使用方法

  • index.js
import { createStore, applyMiddleware, compose } from 'redux';
  import reducer from './reducer';

  import thunk from 'redux-thunk';

  // 解决 redux-devtools-extension 使用问题
  const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;

  const enhancer = composeEnhancers(
    applyMiddleware(thunk)
  );
  const store = createStore(reducer, enhancer);
  • actionCreators.js
import { INIT_LIST_ACTION } from './actionTypes';
    import axios from 'axios';
  
  export const initListAction = (data) => ({
    type: INIT_LIST_ACTION,
    data
  });
  
  export const getTodoList = () => {
    return (dispatch) => {
      axios.get('/api/...').then(res => {
        const data = res.data;
        const action = initListAction(data);
        dispatch(action);
      })
    };
  };
  • reducer.js
import { INIT_LIST_ACTION } from './actionTypes';

  const defaultState = {
       inputValue: "",
       list: []
    };

  export default (state = defaultState, action) => {
    if(action.type === INIT_LIST_ACTION) {
      const newState = JSON.parse(JSON.stringify(state));
      newState.list = action.data;
      return newState;
    }
    return state;
  }
  • actionTypes.js
export const INIT_LIST_ACTION = 'init_list_action';

参考: redux-thunk

redux-saga

功能: 处理react异步请求数据,适用于大型项目

使用方法

  • index.js
import { createStore, applyMiddleware, compose } from 'redux';
  import reducer from './reducer';
  import createSagaMiddleware from 'redux-saga';
  import todoSaga from './sagas';

  const sagaMiddleware = createSagaMiddleware();
  const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;

  const enhancer = composeEnhancers(
    applyMiddleware(sagaMiddleware)
  );
  const store = createStore(reducer, enhancer);
  sagaMiddleware.run(todoSaga);
  • reducer.js
import { INIT_LIST_ACTION } from './actionTypes';

  const defaultState = {
       inputValue: "",
       list: []
    };

  export default (state = defaultState, action) => {
    if(action.type === INIT_LIST_ACTION) {
      const newState = JSON.parse(JSON.stringify(state));
      newState.list = action.data;
      return newState;
    }
    return state;
  }
  • sagas.js
// takeEvery 在每个 GET_TODO_LIST action 被 dispatch 时调用 getTodoList
  // 允许并发(译注:即同时处理多个相同的 action)
  
  // put 相当于store中的dispatch方法,派发action
  import { takeEvery, put } from 'redux-saga/effects';
    import { GET_TODO_LIST } from './actionTypes';
    import { initListAction } from './actionCreators';
    import axios from 'axios';

    function* getTodoList() {
    try {
      const res = yield  axios.get('/list.json');
      const action = initListAction(res.data);
      yield put(action);
    }catch (e) {
      console.log("list.json 网络超时");
    }
  }

  function* mySaga() {
       yield takeEvery(GET_TODO_LIST, getTodoList);
  }

  export default mySaga;
  • actionCreators.js
import { GET_TODO_LIST } from './actionTypes';
  export const getTodoList = () => ({
    type: GET_TODO_LIST
  });
  • actionTypes.js
export  const INIT_LIST_ACTION = 'init_list_action';
  export  const GET_TODO_LIST = 'get_todo_list';

参考: redux-saga

相关推荐