title: React, updating state in child component using props after async call in parent component
body: <p>I'm building a weather app, and I'm looking for some advice for best practices for updating state in a child component based on props sent from parent component AFTER an async call from parent component.</p>
  
  <p>I have a parent component that makes an async/await call in the <code>componentDidMount()</code> method to the <code>navigator.geolocation</code> and returns latitude and longitude which I want to send to the child component as props. Then, in the child component I need do an async/await call to the OpenWeatherMap API using the lat and long from the props. I then need to <code>setState()</code> using the <code>response</code>. I can't use <code>componentDidMount()</code> in the child because it mounts before the parent async/await call returns.</p>
  
  <p>The problem is the application flow: The parent component mounts and renders, sending props to child as <code>null</code>. The child component mounts and renders with <code>null</code> props. Then, the async/await returns a response in parent, sets <code>lat</code> and <code>long</code> from response to state in the <code>componentDidMount()</code>, parent re-renders and sends props to child with correct values as <code>lat</code> and <code>long</code>. Child component updates with correct values in props. Now, at this point I need to <code>setState()</code> with those props, however I obviously can't do it in <code>componentDidUpdate()</code> without re-rendering into a infinite loop.</p>
  
  <p>So, what's a good way to accomplish this task?</p>
  
  <p><strong><em>PARENT COMPONENT:</em></strong></p>
  
  <pre><code>class Container extends React.Component {
    state = {
      cityState: {
        city: "",
        state: ""
      },
      latLong: {
        lat: null,
        long: null
      }
    };
  
    componentDidMount() {
      this.getCityAndState();
    }
  
    getCityAndState() {
      let latlng = "";
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(async position =&gt; {
          latlng = `${position.coords.latitude},${position.coords.longitude}`;
  
          const response = await googleGeolocation.get(
            `json?latlng=${latlng}&amp;location_type=APPROXIMATE&amp;result_type=locality&amp;key=${APIkey}`
          );
  
          this.setState({
            cityState: {
              city: response.data.results[0].address_components[0].long_name,
              state: response.data.results[0].address_components[2].short_name
            },
            latLong: {
              lat: position.coords.latitude,
              long: position.coords.longitude
            }
          });
        });
      }
    }
  
    render() {
      return (
        &lt;div className="container"&gt;
          &lt;LocationTime location={this.state.cityState} /&gt;
          &lt;Forecast location={this.state.latLong} /&gt;
        &lt;/div&gt;
      );
    }
  }
  </code></pre>
  
  <p><strong><em>CHILD COMPONENT:</em></strong></p>
  
  <pre><code>class Forecast extends React.Component {
    state = {
      today: {},
      secondDay: {},
      thirdDay: {},
      fourthDay: {},
      fifthDay: {}
    };
  
    async componentDidUpdate() {
      ********** A bunch of logic in here to extract Weather API response 
  into 5 separate arrays which will each be sent to the &lt;Day /&gt; child components
  after setting the state to those arrays(which doesn't work in this 
  life-cycle method, currently) **********
  
    }
  
    render() {
      return (
        &lt;div className="forecast"&gt;
          &lt;Day forecast={this.state.today} /&gt;
          &lt;Day forecast={this.state.secondDay} /&gt;
          &lt;Day forecast={this.state.thirdDay} /&gt;
          &lt;Day forecast={this.state.fourthDay} /&gt;
          &lt;Day forecast={this.state.fifthDay} /&gt;
        &lt;/div&gt;
      );
    }
  }
  </code></pre>
  
  <p>P.S. I always ask convoluted questions that end with fairly simple answers, lol</p>