React useEffect Hook

In this part, we will learn about React useEffect hook. useEffect hook is used to give effect or side effect once the application get rendered, as an argument for useEffect we usually go with function.

useEffect

By using this useEffect() hook, you can tell React that your component needs to do something after render. Simply, with this hook, you can decide what to show after rendering the project. useEffect Hook runs after every render. Data fetching, logging in, and manually changing the DOM in React components are all examples of side effects.

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMountcomponentDidUpdate, and componentWillUnmount combined.

There are two types of side effects: Effect those don’t need cleanup and Effect those need cleanup.

Effects Without Cleanup

In many project or large projects, we sometimes need to add some code to run after DOM rendered. Network requests, manual DOM mutations, and logging are common examples of effects, and these don’t need a cleanup.

Example without useEffect Hook

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

  componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

The above example is class component with componentDidMount and componentDidUpdate. In this code, we are changing name after DOM gets rendered. It is quite complicated and hard coded. One more thing you need to know is effect scheduled with componentDidMount and componentDidUpdate stops the browser to update the screen.

Example with useEffect Hook

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

This is the same example as the above one, here we have used useEffect hook to do the same work which looks pretty simple and straightforward than above example. And using useEffect hook won’t block the browser from refreshing the DOM.

Why is useEffect called inside a component?

By placing useEffect in the component, we can actually access the variable of state or any props. We don’t need a special API to read it — it’s already in the function scope. Hook supports JavaScript closures and avoid introducing React-specific APIs because JavaScript already provides the solution.

Effects With Cleanup

As we have seen, how to express side effect which don’t require any cleanup. Also, some effects do need cleanup. For example, we might want to set up a subscription to some external data source. In that case, we required the cleanup, so we don’t have to face memory leak.

Example without useEffect hook

In a React class, We need to hard code the subscription using componentDidMount and to perform cleanup we need to use componentWillUnmount. For example, we have here ChatAPI module that let us subscribe to a friend online status.

class FriendStatus extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOnline: null };
    this.handleStatusChange = this.handleStatusChange.bind(this);
  }

  componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }
  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }
  handleStatusChange(status) {
    this.setState({
      isOnline: status.isOnline
    });
  }

  render() {
    if (this.state.isOnline === null) {
      return 'Loading...';
    }
    return this.state.isOnline ? 'Online' : 'Offline';
  }
}

As we can see, how componentDidMount and componentWillUnmount need to mirror each other. This is what we don’t need because these lifecycle methods force us to split the logic even though they are related to the same effect.

Example using useEffect hook

You might be thinking that here also we need separate effect to perform cleanup. But the code is tightly related to useEffect, which is designed to keep it together, so basically we don’t need another effect to perform cleanup as above example. If your effect returns a function, React will run it when it is time to clean up:

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

Basic Example of useEffect Hook:

import React from 'react';
import { useState, useEffect } from 'react';

function App(){
  const [before,after] = useState(0);
  const updateMe = ()=> after(before+1);
  useEffect(()=> {after(5)})
  return <div><h1>This page is clicked {before}</h1>
              <button onClick={updateMe}> click me</button>
  </div>
}
export default App;

We have the same code as above, Here we added useEffect method in that we have update value to 5, so if our project loads or renders then by default we will get value of before to 5. Also remember we if we click the button here, the value won’t change because we have useEffect here which will reset the value to 5 even if we click the button.

Output

useEffect hook

Output after 5 clicks:

useEffect hook

Only First Time Render With useEffect

useEffect(() => //code here ,[])

If we want to render the effect one time, then we need to pass an empty array as a second parameter.

Controlled Render With useEffect

useEffect(()=> //code here,[prop])

If we want to render on a certain condition or something like props, then we need to pass the condition or props in array.

Reactjs Guru
Reactjs Guru

Welcome to React Guru, your ultimate destination for all things React.js! Whether you're a beginner taking your first steps or an experienced developer seeking advanced insights.

React tips & tutorials delivered to your inbox

Don't miss out on the latest insights, tutorials, and updates from the world of ReactJs! Our newsletter delivers valuable content directly to your inbox, keeping you informed and inspired.

3 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents