Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactjs Life Cycle Function Rendering Twice

Tags:

reactjs

I have a question about the mechanics of componentDidMount. I'm building out a weather app that uses an external api to get forecast data for a city.

My Forecast Container is built like this

var React = require('react');
var Forecast = require('../components/Forecast');
var weatherHelpers = require('../utils/weather');

var ForecastContainer = React.createClass({
  getInitialState: function(){
    return {
      isLoading: true,
      forecastData: {}
    }
  },

  componentDidMount: function(){
    weatherHelpers.getCityForecast(this.props.routeParams.city)
    .then(function(results){
      this.setState({
        isLoading: false,
        forecastData: results
      })
    }.bind(this))
  },

  render: function() {
    return (
      <Forecast
        city={this.props.routeParams.city}
        isLoading={this.state.isLoading}
        forecastData={this.state.forecastData}
      />
      )
  }
});

module.exports = ForecastContainer;

I'm using axios to send an http get request to the weather api and storing the functionality inside a helper file called weatherHelpers.

function Forecast(props) {
  console.log(props)
  return (
    <div style={styles.container}>Forecast component</div>
  )
}

When I log props from my Forecast component, it is logged twice. Once with the initial state and again with the updated state. Is this just state life operates: a lag between initial state and running instructions inside componentDidMount? Is there a re-rendering of my component (hence the two console logs). If so, what is the mechanism that is at work. How is the component listening to it's state?

like image 627
Coder_Nick Avatar asked Mar 22 '26 00:03

Coder_Nick


1 Answers

It's because render runs before componentDidMount in the lifecycle (see React documentation).

The order is:

constructor()
componentWillMount()
render()
componentDidMount()

By the time componentDidMount has run, render has already run. The state change in componentDidMount then triggers another render.

Edit

My old (incorrect, but modified now) answer is below, but something else to keep in mind. If you changed componentDidMount to componentWillMount, it would still render twice, because of the promise:

weatherHelpers.getCityForecast(this.props.routeParams.city).then(...

When the component is initially rendered, componentWillMount would run, set up the promise, and then render itself. Then the promise completes, updates the state, and React renders again based on the state change.

like image 129
Jim Stewart Avatar answered Mar 24 '26 13:03

Jim Stewart



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!