Email - harun.bspt2014@gmail.com Phone - +8801717615827

No-constructor-for-stateful-component

We’ve all been taught that the constructor is where we initialize our instance properties, state in this case. And thats true till ES-6. However, that is no more true, for the upcoming ES.next class properties proposal.

With it we can now define class properties directly, like this.

class Foo extends Component {
  state = { loading: true };
  ...
}

Babel will transpile your code and add a constructor for you behind the scenes. Here is the output from Babel when we transpile the code snippet above.

class Foo extends Component {
    constructor (...args) {
        var _temp;

        return (_temp = super(...args), (this.state = { loading: true}), _temp )
    }
}

Note that Babel is actually passing all args — not just props — down to super. It is also taking super’s return value and passing it back to the caller.

A hypothetical ES6 Class Component might look something like this (over-simplified without error checking, of course).

class Foo extends Component {
  constructor(props) {
    super(props);
    this.state = { loading: true };
  }

  async componentDidMount() {
    const data = await loadStuff();
    this.setState({ loading: false, data });
  }
  render() {
    const { loading, data } = this.state;
    return (
      {loading ? <Loading /> : <View {...data} />}
    );
  }
}

We initialize our state in the constructor, asynchronously load our data in componentDidMount, and render our View component based on the loading state.

Now without the constructor (using ES-7) I can shorten it like below.

class Foo extends Component {
  state = { loading: true };

  async componentDidMount() {
    const data = await loadStuff();
    this.setState({ loading: false, data });
  }
  render() {
    const { loading, data } = this.state;
    return (
      {loading ? <Loading /> : <View {...data} />}
    );
  }
}

Initializing state with props – What about when you need to derive your initial state from props, say for initializing a default value? Surely we need the constructor for that?

class Foo extends Component {

  constructor(props) {
    super(props);
    this.state = {
      color: this.props.initialColor
    };
  }
  render() {
    const { color } = this.state;
    return (
      <div>
       {color}
      </div>
    );
  }
}

Nope! Again, class properties to the rescue! We have access to both this and props.

class Foo extends Component {
  state = {
    color: this.props.initialColor
  };

  ...
}

We’ve seen that for setting our initial state, we no longer need a constructor (or any other instance property for that matter). We also don’t need it for binding methods to this. Same for setting initial state from props. And we would most definitely never fetch data in the constructor.

Why then would we ever need the constructor in a React component?

An use-case The below parent component (FetchWeather) only fetches the weather and update the state with the fetched data. Andthen the passes that state down as props to the child RenderWeather component.

This code is slight modification from the code in https://github.com/Kennypee/Weather-Scanner – that just fetches the weather and renders it.

import React from "react";
import RenderWeather from "./components/RenderWeather";

class FetchWeather extends React.Component {

    state = {
    temperature: undefined,
    city: undefined,
    country: undefined,
    humidity: undefined,
    error: undefined
}
  // getWeather is a method we'll use to make the api call
  getWeather = async () => {

    // the city and the country is hardcoded here
    const api_call = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=london,uk&appid=8d2de98e089f1c28e1a22fc19a24ef04`);

    const response = await api_call.json();

    console.log(response);


      this.setState({
        temperature: response.main.temp,
        city: response.name,
        country: response.sys.country,
        humidity: response.main.humidity,
        description: response.weather[0].description,
        error: ""
      })
  }

  componentDidMount() {
    this.getWeather();
  }

  render() {
    return (
            <div className="col-xs-7 form-container">

                <RenderWeather
                temperature={this.state.temperature}
                city={this.state.city}
                country={this.state.country}
                humidity={this.state.humidity}
                error={this.state.error}
                />
            </div>
      </div>

    )
  }
}
export default FetchWeather;

Now the child RenderComponent, which is a stateless component that only renders that data.

import React from "react";

class RenderWeather extends React.Component{
    render(){
        return(
            <div className="weather-info">
                {
                    this.props.country && this.props.city && <p className="weather__key">Location:
                        <span className="weather__value">  {this.props.city}, {this.props.country}</span>
                    </p>
                }

                {
                    this.props.temperature && <p className="weather__key">Temperature:
                        <span className="weather__value">  {this.props.temperature}</span>
                    </p>
                }

                {
                    this.props.humidity && <p className="weather__key">Humidity:
                        <span className="weather__value">  {this.props.humidity}</span>
                    </p>
                }

                {
                    this.props.error && <p className="weather__error">{this.props.error}</p>
                }
            </div>
        )
    }
}

export default RenderWeather;

Further Reading

https://www.robinwieruch.de/react-state-without-constructor/?fbclid=IwAR2tELzjRnsNxovZ43PL6GjunhUPZ6kSac46S1ypj5ltspEIiJbOt-Vs1GA

Dr. Harun
Dr. Harun

Dr. Md. Harun Ar Rashid, MPH, MD, PhD, is a highly respected medical specialist celebrated for his exceptional clinical expertise and unwavering commitment to patient care. With advanced qualifications including MPH, MD, and PhD, he integrates cutting-edge research with a compassionate approach to medicine, ensuring that every patient receives personalized and effective treatment. His extensive training and hands-on experience enable him to diagnose complex conditions accurately and develop innovative treatment strategies tailored to individual needs. In addition to his clinical practice, Dr. Harun Ar Rashid is dedicated to medical education and research, writing and inventory creative thinking, innovative idea, critical care managementing make in his community to outreach, often participating in initiatives that promote health awareness and advance medical knowledge. His career is a testament to the high standards represented by his credentials, and he continues to contribute significantly to his field, driving improvements in both patient outcomes and healthcare practices.

Translate »
Register New Account