How to solve data loading issue in React redux

前端 未结 2 1217
陌清茗
陌清茗 2021-01-26 05:27

I am trying to figure out how can i manage/display this component when data is still loading.

I am using react redux for this case.

any suggestion for solving th

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-26 06:09

    Well, you can add two more actions into your existing list of actions. One for getting the status of the beginning of the API call and one for any error. Sort of like this:

    import * as types from "./actionTypes";
    
    export function beginApiCall() {
      return { type: types.BEGIN_API_CALL };
    }
    
    export function apiCallError() {
      return { type: types.API_CALL_ERROR };
    }
    

    Then you can make use of these actions by dispatching them at the right time.

    export const getWorkexperience = () => dispatch => {
        dispatch(beginApiCall());
        axios
            .get('/api/workexperiences')
            .then(res => 
                dispatch({
                    type: GET_WORKEXPERIENCE,
                    payload: res.data
                })
            ).catch (err => dispatch(apiCallError(error)););
    };
    

    Then you have to create a new reducer for this action. Writing a reducer for this is a little tricky. You need to store the number of API calls in progress and increment or decrement them based on their status. For that, you can append _SUCCESS to your existing action type in all your action creators and reducers.

    import * as types from "../actions/actionTypes";
    import initialState from "./initialState";
    
    function actionTypeEndsInSuccess(type) {
      return type.substring(type.length - 8) === "_SUCCESS";
    }
    
    export default function apiCallStatusReducer(
      state = initialState.apiCallsInProgress,
      action
    ) {
      if (action.type == types.BEGIN_API_CALL) {
        return state + 1;
      } else if (
        action.type === types.API_CALL_ERROR ||
        actionTypeEndsInSuccess(action.type)
      ) {
        return state - 1;
      }
    
      return state;
    }
    
      //initialState.js
        export default {
          state1: [],
          state2: [],
          apiCallsInProgress: 0
        };
    

    Once inside your component, after you make a fetch request, you can use the state of this reducer to render a spinner or anything you want just by fetching it from the reducer.

      const loading = useSelector((state) => state.apiCallsInProgress > 0);
    

    or you can access it via mapStateToProps like this, which I see you have used to fetch props in your component.

    const mapStateToProps = (state) => ({
        resume: state.resume,
        isAuthenticated : state.auth.isAuthenticated,
        auth: state.auth,
        loading: state.apiCallsInProgress > 0
    });
    

    And you can return the content of the function like this.

     {loading ? (
           Loading...
          ) : (
            
    My component
    )}

提交回复
热议问题