Petrus K.
Petrus K.

Reputation: 840

What is the preferred design pattern to delay rendering of a component in React?

I'm currently defering rendering of a component by initializing a state readyToRender to false and setting it to true once I have the data needed to render the UI.

My render function looks something like:

if (this.state.readyToRender) {
  return (
    // render component
)} else {
  return false; // don't render component
}

Is this the correct pattern to utilize for this problem or is there a better way to solve this?
Related questions:

Upvotes: 2

Views: 598

Answers (1)

omerts
omerts

Reputation: 8838

First of all, we try to derive the "loaded" state from the data, instead of holding it in this.state. While data is not available, we show a spinner, but you might as well show nothing.

So for example:

const TextShower = (props) => {
  if (props.text) {
    return <div>{props.text}</div>
   }

   return <img src='https://s31.postimg.org/g3992fx7v/477.gif' />
}

Fiddle: https://jsfiddle.net/omerts/8r3dh6hw/

We have also created a high-order component for taking care of this (loader image changed so the example works):

const loaderComponent = (ComposedComponent, predicate) => {
  return (props) => {
    const isLoading = predicate && predicate(props)

    if (isLoading) {      
      return <div className='loading-data'>
                <img src='https://s32.postimg.org/8w18tbrlx/477_1.gif' />
             </div>
    }

    return <ComposedComponent {...props} />
  }
}

Usage:

const TextShower = (props) => { 
  return <div>{props.text}</div>   
}

const LoaderTextShower = loaderComponent(TextShower, 
                                         (props) => !props.text)

Fiddle: https://jsfiddle.net/omerts/4edgbhmz/

From the "Thinking in React" doc:

Can you compute it based on any other state or props in your component? If so, it's not state.

Upvotes: 1

Related Questions