react

Redux中介軟體的使用

reduxthunk功能:使用中介軟體可以在action中返回函式,可以用來處理ajax非同步請求

>

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

Facebook Profile photo
Written by Nat
This is the author box. A short description about the author of this article. Could be their website link, what they like to read about and so on. Profile