React before hooks class based React - vonschappler/Ultimate-React GitHub Wiki

A bit of history:

Before 2019, components in React were written as classes with a render() function, responsible for displaying the component on screen, just like displayed in the "barebones"code for a simple counter below.

import React from 'react';

class Counter extends React.Component {
  // this is equivalent of the function body
  render() {
    return (
      <div>
        <button>-</button>
        <span>0</span>
        <button>+</button>
      </div>
    );
  }
}

export default Counter;

Classes components do not support states, so in order to add states to a component, we need to set a constructor function, where we define the states as a huge object of states, instead of a single state variable for each state as done in functional components.

Also the way to access some state is a bit different. Because we are using classes, the use o the keywork this (which points to the current components insntace rendered) and the property state are required in order to access the state.

// some code here...

constructor(props) {
  super(props);
  this.state = {count: 5};
}

// some more code here...

// accessing the state with the key words "this" and "state"
<span>{this.state.count}</span>

In order to create event handlers to classes components, we need to define those as class methods, always outside the render() function, because class components requires that the code inside the render() function to be as clean as possible. Not that to handle events in class components, it's necessary to bind them manually inside the constructor method, so they can be linked to the component instance in order to set states when those are updated on event handlers.

// some code here...
constructor(props) {
  super(props);
  this.state: {count: 0}
  this.handleDecrement: this.handleDecrement.bind(this);
  this.handleIncrement: this.handleIncrement.bind(this);
  this.handleReset: this.handleReset.bind(this);
}

handleDecrement() {
  this.setState((currState) => {
    return {count: currState.count - 1};
  });
}

handleIncrement() {
  this.setState((currState) => {
    return {count: currState.count + 1};
  });
}

handleReset() {
  this.setState({count: 0});
}

// some code here...
<button onClick={this.handleDecrement}>-</button>
<button onClick={this.handleIncrement}>+</button>
<button onClick={this.handleReset}>Reset counter</button>


// some more code here

IMPORTANT:

Even though the render() function needs to be as clean as possible, some small and simple logic can still be added to it!

The full code for a simple counter Component is displayed below:

import React from 'react';

class Counter extends React.Component {
  constructor(props) {
    super(props);

    this.state = { count: 5 };
    this.handleDecrement = this.handleDecrement.bind(this);
    this.handleIncrement = this.handleIncrement.bind(this);
    this.handleReset = this.handleReset.bind(this);
  }

  handleDecrement() {
    this.setState((currState) => {
      return { count: currState.count - 1 };
    });
  }

  handleIncrement() {
    this.setState((currState) => {
      return { count: currState.count + 1 };
    });
  }

  handleReset() {
    this.setState({ count: 0 });
  }

  render() {
    const date = new Date('june 21 2027');
    date.setDate(date.getDate() + this.state.count);

    return (
      <>
        <div>
          <button onClick={this.handleDecrement}>-</button>
          <span>
            {date.toDateString()} [{this.state.count}]
          </span>
          <button onClick={this.handleIncrement}>+</button>
        </div>
        <div>
          <button onClick={this.handleReset}>Reset counter</button>
        </div>
      </>
    );
  }
}

export default Counter;

Differences between functional components and class components:

Function Components Class Components
Introduced in v16.8 (2019, with hooks) v0.13 (2015)
How to create Any type of JavaScript function ES6 classes definition, extending React.Component
Reading props Destructuring or props.x this.props.x
Local State useState hook this.state = {state: value}
this.setState()
Side effects/lifecycle useEffect hook lifecycle methods
Event handlers functions class methods
Returning JSX Return the JSX from function Return JSX from render() method
Advantages
  • Easier to build (less boilerplate code)
  • Cleaner clode: useEffect combines all lifecycle-related code in a single place
  • Easier to share stateful logic
  • No need to use the this keywork
  • Lifecyle might be easier to understand for beginners

Component lifecycle in class components:

They are special methods that all methods that each react component has access to, so we can manage side effects on each point of the componet lifecycle.

  • componentDidMount(): called imediatelly after the render (similar to useEffect with empty dependency array)
  • componentDidUpdate(prevProps, prevState): called only during re-renders (similar to useEffect with variables inside the dependency array)
  • componentWillUnmount(): called after a component is unmounted, (similar to return a cleanup function returned from useEffect)
⚠️ **GitHub.com Fallback** ⚠️