How to solve data loading issue in React redux

前端 未结 2 1216
陌清茗
陌清茗 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:03

    One of the common ways to deal with presentation of the component, especially if it is a container, is to implement loading activity indicator, which would disappear once you have the data to display. Just make sure to implement loading boolean in your local state, and once you confirm that data is there, change loading to false.

    async componentWillMount() {
      await getWorkexperience();
      this.setState({
         loading: false,
      });
    }
    
    ...
    
    render() {
      const { data, loading } = this.state;
    
      return (
        <div>
          {/*
            Check the status of the 'loading' variable. If true, then display
            the loading spinner. Otherwise, display the data.
          */}
          {loading ? <LoadingSpinner /> : <ResultsComponent results={data} />}
        </div>
      );
    
    }
    

    Is this something you were looking for?

    Among ready made solutions there are packages that can be used right away:

    • https://www.npmjs.com/package/react-activity
    • https://www.npmjs.com/package/react-activity-indicator
    0 讨论(0)
  • 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...
          ) : (
            <div>My component</div>
    )}
    
    0 讨论(0)
提交回复
热议问题