React Native: make an API request, set State and THEN render?

Sorry if it's obvious in the documentation somewhere, but I'm trying to wait for my state to be set on the parent component before rendering the child component:

I quote:

class Parent extends Component {

  componentWillMount() {
    firestack.database.ref()
      .then((snapshot) => {
        this.setState({myVal: snapshot.val})
      })
  }

  render() {
    // Renders before request finishes setting state,
    // Child component receives an undefined val
    return (
      <ChildComponent
        myVal={this.state.myVal}
      />
    )
  }
}

      

My render hits before the request completes, so I cannot pass the new state to the constructor of the child components. How can I get it right? Hope this is bad hanging fruit for someone.

+3


source to share


3 answers


First, I recommend moving the asynchronous request request to componentDidMount

. Not necessary, but this is the best moment in the life cycle. Your component will have to handle anyway myVal == undefined

.

Then, don't allocate the child component until myVal

:

render() {
  return (
    <div>
      { this.state.myVal && <ChildComponent myVal={this.state.myVal} /> }
    </div>
  )
}

      

Or maybe do a spinner instead:



render() {
  return (
    <div>
      { this.state.myVal 
        ? <ChildComponent myVal={this.state.myVal} />
        : <Spinner />
      }
    </div>
  )
}

      

Note:

  • You cannot use if

    JSX internally, so &&

    less-kosher use must be used to preserve syntax . The big picture.

  • You can have a this.state.isReady

    boolean instead of asking for a specific value. Another common pattern.

  • If ChildComponent

    is the only element you are going to display, you may not need a wrapper <div />

    , but you are for some reason for some reason.

+4


source


If the parameter myVal

is required ChildComponent

, you just need to do it in the parent:

return (
  {this.state.myVal !== undefined &&
    <ChildComponent
      myVal={this.state.myVal}
    />
  }
)

      



Then the reaction will give an empty string for the first time, and after changing the state it will be displayed again with the filled value myVal

.

Also, as said in another answer, it is much better to use componentDidMount

.

+2


source


It is recommended that you make API calls within componentDidMount

rather than componentWillMount

. https://facebook.github.io/react/docs/react-component.html#componentdidmount

The setting state in this method will cause a re-render.

0


source







All Articles