Put rendering on-hold until initial fetch is done

Author: rpribadi-dsCreated Jul 14, 2016Updated Feb 25, 2018

Hi @davezuko , I have a question on how to postpone child-rendering until a certain condition is met.

For example: Let's say I have an "app" component. And on top of that, I have 2 modules inside my route: /products -> accessing Product module. /users -> accessing User module.

The app will render the children component based on its route. but, on "app" component, there's a necessary API that should be called first before rendering its children component.

App/Component.js

javascript
class CoreLayout extends React.Component {
  componentWillMount() {
    this.props.fetchInitialSettings();
  }

  render() {
    return (
      <div>
        <Header />
        {this.props.children}
        <Footer />
      </div>
    );
  }
}

If the user access '/' directly, then it should not be a problem. but if the user access '/products' directly, can we ensure the "this.props.fetchInitialSettings();" is done first on the "app" then continue rendering the children component?

I've tried to modified App/Component.js to look like this:

javascript
class CoreLayout extends React.Component {
  componentWillMount() {
    this.props.fetchInitialSettings();
  }

  componentDidMount() {
    this.node = ReactDOM.findDOMNode(this.refs.container);
    this.renderContent();
  }

  componentWillReceiveProps(newProps) {
    this.renderContent(newProps);
  }

  renderContent(props) {
    props = props || this.props;

    if (props.firstLoadDone) {
      ReactDOM.render(<Provider store={props.store}>{props.children}</Provider>, this.node);
    }
    else {
      ReactDOM.render(<div />, this.node);
    }
  }

  render() {
    return (
      <div>
        <Header />
        <div className='main' ref='container'></div>
        <Footer />
      </div>
    );
  }
}

But I'm not sure wether this is the right approach. I used a flag in the state, "firstLoadDone", to keep track wether fetchInitialSettings is done or not. And only after it's done, componentWillReceiveProps will be called, and then I render the children component.

However, it doesn't feel right. For example, I have to wrap the children inside "Provider" again, together with the "store" and pass down the original "store" to children component, otherwise, the children component will loose their access to original store.

And I'd like to use this approach for deeper route, for example: the user access /products/31 directly. Meaning:

  1. Render app component
  2. Wait for necessary API for app is done
  3. if done, render product component
  4. Wait for necessary API for product is done
  5. if done, render product-detail component
  6. done

Thanks in advance

Regards, Riki

Source: dvdzkwsk/react-redux-starter-kit