React: Component Lifecycle

Component Lifecycle Overview

Component Lifecycle Diagram

At this point we can introduce componentDidMount, componentDidUpdate & componentWillUnmount.

Before this we just had our constructor and render sections of our application.

Render should always contain the EJS that will render on the page. This is where the visual elements should be living.

Constructor is where you initialize your state. And previously we were doing our data fetching there. However this is not actually best practice.

In the basic lifecycle of a component, first we let the component render, then once it has renders everything inside of componentDidMount will fire as a result of the rendering finishing. This is where we should (according to best practice) be putting our data calls.

Take a look at the short application we were working on in the previous post here.

Then here we can see that we have moved the location fetching from the app component to the componentDidMount function.

class App extends React.Component {
  // javascript class that initializes state
  constructor(props) {
    super(props);

    this.state = { lat: null, long: null, errorMessage: "" };
  }

  componentDidMount() {
    window.navigator.geolocation.getCurrentPosition(
      (position) =>
        this.setState({
          lat: position.coords.latitude,
          long: position.coords.longitude,
        }),
      (err) => {
        this.setState({ errorMessage: err.message });
      }
    );
  }

  // react requires us to define render
  render() {
    // if there is an error message and no position data
    if (this.state.errorMessage && !this.state.lat) {
      return (
        <LatLongCard>
          <div className="description">Error: {this.state.errorMessage}</div>
        </LatLongCard>
      );
      // if there is no error message and there IS position data
    } else if (!this.state.errorMessage && this.state.lat) {
      return (
        <LatLongCard>
          <div className="description">Latitude: {this.state.lat}</div>
          <div className="description">Longitude: {this.state.long}</div>
        </LatLongCard>
      );
      // if no error message and no position data
    } else {
      return (
        <LatLongCard>
          <div className="description">Loading Location...</div>
        </LatLongCard>
      );
    }
  }
}

The application still functions the same but this is the accepted organizational practice.

Alternate Method of Initializing State

Currently when we are initializing state we are typing out the constructor function manually.

// javascript class that initializes state
constructor(props) {
    super(props);

    this.state = { lat: null, long: null, errorMessage: "" };
}

However because of Babel we can actually shorten this to a much easier bit of code that Babel will compile into a constructor function.

// initialize state
  state = { lat: null, long: null, errorMessage: "" };