React useReducer async data fetch

前端 未结 6 687
臣服心动
臣服心动 2020-11-30 22:36

I\'am trying to fetch some data with new react useReducer API and stuck on stage where i need to fetch it async. I just don\'t know how :/

How to place data fetching

6条回答
  •  北荒
    北荒 (楼主)
    2020-11-30 23:15

    I wrapped the dispatch method with a layer to solve the asynchronous action problem.

    Here is initial state. The loading key record the application current loading status, It's convenient when you want to show loading page when the application is fetching data from server.

    {
      value: 0,
      loading: false
    }
    

    There are four kinds of actions.

    function reducer(state, action) {
      switch (action.type) {
        case "click_async":
        case "click_sync":
          return { ...state, value: action.payload };
        case "loading_start":
          return { ...state, loading: true };
        case "loading_end":
          return { ...state, loading: false };
        default:
          throw new Error();
      }
    }
    
    function isPromise(obj) {
      return (
        !!obj &&
        (typeof obj === "object" || typeof obj === "function") &&
        typeof obj.then === "function"
      );
    }
    
    function wrapperDispatch(dispatch) {
      return function(action) {
        if (isPromise(action.payload)) {
          dispatch({ type: "loading_start" });
          action.payload.then(v => {
            dispatch({ type: action.type, payload: v });
            dispatch({ type: "loading_end" });
          });
        } else {
          dispatch(action);
        }
      };
    }
    

    Suppose there is an asynchronous method

    async function asyncFetch(p) {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve(p);
        }, 1000);
      });
    }
    
    
    wrapperDispatch(dispatch)({
      type: "click_async",
      payload: asyncFetch(new Date().getTime())
    });
    

    The full example code is here:

    https://codesandbox.io/s/13qnv8ml7q

提交回复
热议问题