1

I am beginner to React and Redux and I not found any example of how to do some kind of loading screen before I fetch first API call to get some informations what are needed for app to render (such as if user is logged, some other data)

I already have React App what using Redux and React-Router. I need to create some loading screen before HomePage is rendered. This loading screen will be active until I get response from API. After I get response I will dispatch them into store and disable loading screen.

I found example how I need it here: https://boss.gg/ (They using React too)

David Bubeník
  • 463
  • 6
  • 17
  • Check this question, I imagine it could help: https://stackoverflow.com/questions/40987309/react-display-loading-screen-while-dom-is-rendering – Rafael Aug 26 '18 at 21:33

1 Answers1

1

Divde your actions up in different states: pending, success, error. When your request is pending your component can show a loading screen that's replaced when the request is fulfilled or errors out. With the help of redux-thunk you can create asyc actions.

In somewhat pseudo-code this would work like this:

Your actionTypes:

export const GET_EXAMPLE_ERROR = 'GET_EXAMPLE_ERROR':
export const GET_EXAMPLE_SUCCESS = 'GET_EXAMPLE_SUCCESS':
export const GET_EXAMPLE_PENDING = 'GET_EXAMPLE_PENDING':

Your actions:

export function getExampleSuccess(payload) {
  return {
    type: exampleActionTypes.GET_EXAMPLE_SUCCESS,
    payload,
  };
}
export function getExampleError(error) {
  return {
    type: exampleActionTypes.GET_EXAMPLE_ERROR,
    error,
  };
}
export function getExamplePending() {
  return {
    type: exampleActionTypes.GET_EXAMPLE_PENDING,
  };
}
export function getExample() {
  return async dispatch => {
    dispatch(getExamplePending());
    try {
      const result = await exampleService.getData();
      dispatch(getExampleSuccess(result));
    } catch (error) {
      dispatch(getExampleError(error));
    }
  };
}

Your reducer:

export default function exampleReducer(state = initialState.example, action) {
  switch (action.type) {
    case exampleActionTypes.GET_EXAMPLE_ERROR:
      return {
        ...state,
        example: {
          ...state.example,
          error: action.error,
          pending: false,
        },
      };
    case exampleActionTypes.GET_EXAMPLE_SUCCESS:
      return {
        ...state,
        example: {
          ...state.example,
          result: action.payload,
          pending: false,
        },
      };
    case exampleActionTypes.GET_EXAMPLE_PENDING:
      return {
        ...state,
        example: {
          ...state.example,
          error: null,
          pending: true,
        },
      };

    default:
      return state;
  }
}

Your Component:

class ExampleComponent extends React.Component {

    componentDidMount() {
        this.props.getExample();
    }

    render() {
        if( this.props.pending ) {
            return <Loader />;
        }

        return <div>Your component</div>
    }
}

const mapStateToProps => ({
    pending: state.example.pending
});

const mapDispatchToProps => ({
    getExample
})

export default connect(mapStateToProps, mapDispatchToProps)(ExampleComponent)

Note that this is an example of a single call. Your pending state can be a compbination of multiple pending states in different parts of your redux store.

ChezFre
  • 6,502
  • 1
  • 19
  • 25
  • Nice! Thanks this looks good. I will do it this way I think, but I see that example website what I sent using different method. I was going trough their requests and I found, that their loader is above React App away from app root and seems that API call is done even before React wakes up, so fetched data can be injected into React even before his start. Is this possible or they maybe using some other method and its not important because this what u sent me will work fine? – David Bubeník Aug 26 '18 at 20:44
  • There are numerous ways of tackling this problem. Rafaels answer to your original question is a good way to tackle the initial load of your application while this solution will be more versatile to implement in subsequent loading states. – ChezFre Aug 27 '18 at 09:27