Class Components vs Functional Components

Class Components vs Functional Components

In this article, we will be talking about the difference between functional and class components and which one is the most beneficial to use when creating a project

The primary distinction between the two is that while Class Component is a class that extends from React Component and creates a render function that also returns a React Element, Functional Components are just pure Javascript functions that take in arguments known as props and then return a React Element called JSX.

// Class Components
class MyClassComponent extends React.Component {
  render(){
    return (
      <div>Hello World<div>  
    ) 
  }
}

// Functional Components
function MyFunctionComponent (){
  return (
    <div>Hello World<div>  
  )
}

// Functional Components (Arrow Function)
const MyFunctionComponent = ()=> {
  return (
    <div>Hello World<div>  
  )
}

Major Differences Between Class and Functional Components

State

Class components are referred to as stateful components because they implement logic and state, which means they manage how the state changes and how the logic of the component is implemented.

Components without any state are known as stateless components, and you cannot use this.setState inside these components.
Without a render method, it behaves like a regular function.
Since it lacks a lifecycle, lifecycle methods like componentDidMount and other hooks cannot be used. From this definition, we can see that a functional component is a stateless component because they simply accept data and display them in some form that is they are mainly responsible for rendering UI. It accepts properties(props) in function and returns JSX.

LifeCycle

Lifecycle hooks are another feature that cannot be used in functional components.
All lifecycle hooks originate from the React. Component, which you extend in class components, for the same reason as for the state.
Functional components lack lifecycle methods since they are just straightforward JS functions that accept props and return their elements, whereas class components contain methods like componentWillMount, componentDidUpdate, etc.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      points: 0
    };
  }

  static getDerivedStateFromProps(nextProps, nextState) {
    // called before every render (when props or state are changed)
    // returns
    // 1. object for updating state from props
    // 2. or null for no state updates

    if (nextState.points > nextProps.maxPoints) {
      console.log("points = maxPoints ---> reset points");
      return {
        points: 0
      };
    }
    return null;
  }

  shouldComponentUpdate(nextProps, nextState) {
    // returns
    // 1. true if rendering is needed
    // 2. false if rendering is not needed
    return nextState.points % 2 === 0;
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("--- getSnapshotBeforeUpdate");
    console.log("prevProps", prevProps);
    console.log("prevState", prevState);
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
  }

  componentDidMount() {
    // called once when component is mounted to the DOM
    console.log("--- componentDidMount");
  }

  componentWillUnmount() {
    console.log("--- componentWillUnmount");
    // - clearing up timers
    // - cancelling network requests
    // - cleaning up subscriptions
  }

  handleAdd = () => {
    this.setState(state => ({
      points: state.points + 1
    }));
  };

  render() {
    const { points } = this.state;
    return (
      <React.Fragment>
        <h1>Points: {points}</h1>
        <button onClick={this.handleAdd}>ADD</button>
      </React.Fragment>
    );
  }
}

Order

When a function is returned, it can no longer be maintained because Functional components work from top to bottom, while for class Components, Different life cycle methods are kept alive, performed, and triggered based on the phase of the class component after it is created.

Syntax

In Class Components, the render method is necessary to render components and it uses the setState method to manage the state of the application.

class Counter extends React.Component {
  constructor(props) {
   super(props);
   this.state = {counter: ' '}
  }

  increaseCounter(){
    this.setState((state) => {
      return {counter: state.counter + 1};
    });
  }
  render(){
    return (
      <div>{this.state.counter}<div>  
    ) 
  }
}

While in Functional Components, we don’t use the render method to render our components and we make use of hooks to manage our state.

const Counter = ()=> {
  const [counter, setCounter] = useState(0)
  const increaseCounter =() => {
    setCounter(counter + 1)  
  }
  return (
    <div>{counter}<div>  
  )
}

Which Should I Use

There have been so many questions and controversies as to which to use, whether functional or class and I believe that it all comes down to personal preference.

But i advise using Functional Components as most modern-day React/Next Projects are built on Functional Components and other reasons as mentioned below

  1. They assist you in employing optimal practices.
    If your component doesn’t have access to setState(), it will become simpler to distinguish between presentational and container components because you will need to consider your component’s state more.

  2. There is less code and it makes your code a whole lot easier to read

  3. The React team mentioned that there may be a performance boost for functional components in future React versions

Conclusion

So according to all what was said earlier and after comparing pros and cons of both sides, i think it’s comfortable to say that when constructing presentational elements without their own states or requiring access to a lifecycle hook, the most optimal choice of component to use would be the Functional Components, otherwise, you can use Class components and even spice them up with Higher Order Components.