Class and Functional components

class based component with State and Lifecycle

A class-based component is a more complex structure. It is an instance of a class derived from React.Component class. The class must implement a render() member function which returns a React component to be rendered, similar to a return value of a functional component. In a class-based component, props are accessible via this.props.

class MyHello extends React.Component {
  render() {
    return <h2>Hello, {this.props.name}</h2>;
  }
}

Class-based components can have state

Apart from props, the component rendered from a class-based component can depend on its state. Here is an example of a class-based component which maintains a counter in its state. The counter is incremented every time a user clicks on a button which is rendered inside a component.

class MyHello extends React.Component {
  // Define an initial state
  // we can use contructor also to initlize state 
  state = { counter: 0 };
  incrementCounter = () => {
    this.setState({count : this.state.count + 1});
  };
  render() {
    return (
      <React.Fragment>
        <h2>
          Hello, {this.props.name} {this.state.counter} times
        </h2>
        <button onClick={this.incrementCounter}>Say it again</button>
      </React.Fragment>
    );
  }
}

Class-based components can have lifecycle methods

In addition to a state, class-based components can also have lifecycle methods which fire at specific points of a component lifecycle. Those lifecycle methods can be used to fetch the data from remote servers, create objects, such as timers when the component is mounted (rendered to the DOM for the first time), and free them when a component is unmounted from the DOM, determine if the component should be re-rendered if props are changed, and so on.

// Class-based component with lifecycle methods
class MyHello extends React.Component {
  componentDidMount() {
    // The component is mounted - fetch the data from the server
    ...
  }
  componentDidUpdate(prevProps, prevState, snapshot) {
    // The component is updated - update the values
    ...
  }
  componentWillUnmount() {
    // The component is about to be unmounted - clean up
    ...
  }
  render() {
   ...
  }
}

Function based component with State and Lifecycle

Till now we had perception that we can use functional component when there is a state and lifecycle added in component .. let break that !!

Okay wait we just need to look at Hooks first before talking about state in functional Components !!

React Hooks?

React Hooks were invented by the React team to introduce state management and side-effects in function components. It’s their way of making it more effortless to use only React function components without the need to refactor a React function component to a React class component for using lifecycle methods, in order to use have side-effects, or local state. React Hooks enable us to write React applications with only function components.

Unnecessary Component Refactorings: Previously, only React class components were used for local state management and lifecycle methods. The latter have been essential for introducing side-effects, such as listeners or data fetching, in React class components.

import React from 'react';

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button
          onClick={() =>
            this.setState({ count: this.state.count + 1 })
          }>
          Click me
        </button>
      </div>
    );
  }
}
export default Counter;

Only if you didn’t need state or lifecycle methods, React functional stateless components could be used. And because React function components are more lightweight (and elegant), people already used plenty of function components. This came with the drawback of refactoring components from React function components to React class components every time state or lifecycle methods were needed (and vice versa).

import React, { useState } from 'react';
// how to use the state hook in a React function component
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
export default Counter;

In above example we are using state in functional component !!

With Hooks there is no need for this refactoring. Side-effects and state are finally available in React function components. That’s why a rebranding from functional stateless components to function components would be reasonable.

Side-effect Logic: In React class components, side-effects were mostly introduced in lifecycle methods (e.g. componentDidMount, componentDidUpdate, componentWillUnmount). A side-effect could be fetching data in React or interacting with the Browser API. Usually these side-effects came with a setup and clean up phase. For instance, if you would miss to remove your listener, you could run into React performance issues.

// side-effects in a React class component
class MyComponent extends Component {
  // setup phase
  componentDidMount() {
    // add listener for feature 1
    // add listener for feature 2
  }
  // clean up phase
  componentWillUnmount() {
    // remove listener for feature 1
    // remove listener for feature 2
  }
  ...
}
// side-effects in React function component with React Hooks
function MyComponent() {
  useEffect(() => {
    // add listener for feature 1 (setup)
    // return function to remove listener for feature 1 (clean up)
  });
  useEffect(() => {
    // add listener for feature 2 (setup)
    // return function to remove listener for feature 2 (clean up)
  });
  ...
}

Now, if you would introduce more than one of these side-effects in a React class component’s lifecycle methods, all side-effects would be grouped by lifecycle method but not by side-effect. That’s what React Hooks are going to change by encapsulating a side-effect in one hook whereas every hook has its own side-effect with a setup and clean up phase. You will see later in a tutorial how this works for real by adding and removing listeners in a React Hook.

So from above example useState and useEffect is powerful tool for functional components

Last updated