Knowing when the UI is ready in React / Redux Knowing when the UI is ready in React / Redux reactjs reactjs

Knowing when the UI is ready in React / Redux


I'm afraid there is not a universally good way to do this in React, this is "logic" that is related with the structure of your application.

I wanted to display a loader when navigating from one page to another in Single Page Application(SPA) written in react and I faced a similar problem not knowing when to stop displaying it and if all the components in the new page have completed their API calls/renders.

The way I resolved it was:

1) I removed all my API calls from inside my components.

2) Create a Page component to wrap all the components included in that page(invoked by your react router).

3) Perform all requests required for your components simultaneously on navigation(in my case while displaying the loader). For each request that completes, create a promise and inside it create your component dynamically using React.createElement. Pass to the component created the request response and the promise handler as props.

4) Resolve the promise in your component's componentDidMount.

5) Once all the promises are resolved you know the "page" is ready and you can record the value of window.performance.now().

It is hard to provide a minimal code example without a lot of out of context code since this code is spread across the application.


There's more than one way to do what you're asking - but off the top of my head I would do the following:

• Create a perf reducer and call performance.now() right before I make the redux store and add the value to the initial state.

{ perf: { start: '...', end: '...' } }

• Track loading status of initial HTTP requests in a loaded reducer.

{ loaded: { request1: false, request2: false, request3: false } }

• Connect top level component to loaded reducer and check if all requests are complete in componentDidUpdate. If true add end value to perf reducer.

import React from 'react';import { connect } from 'react-redux';class App extends React.Component {  componentDidUpdate(prevProps) {    if (!prevProps.loadingComplete && this.props.loadingComplete) {      this.props.updatePerf(performance.now());    }  }}const mapStateToProps = state => ({  loadingComplete: state.loaded.every(item => item),});const mapDispatchToProps = dispatch => ({  updatePerf(time) {    dispatch({ type: 'SET_ENDING_PERF', payload: time });  },});export default connect(mapStateToProps, mapDispatchToProps)(App);


In our project, we use redux and a couple of actions - trigger, request, success, error.

"Trigger" calls request and throw loading: true into our "smart" component"Request" fetch data and throw them into Success/Error"Success", tells us that everything is fine and data loaded and throw { loading: false, data }

On success/error, we always know that is happening with our application

And of course you can use componentWillReceiveProps(nextProps) {} and check loading flag and data in your component