React Basics: useEffect

React Basics: useEffect

February 14, 2024 - Edited on February 16, 2024

The useEffect hook in React is used for side effects in functional components.

Here's the basic syntax:

useEffect(() => {
  // Side effect code goes here
}, [dependencies]);
// This code will run each time the dependencies change

Let's break down the components of this syntax:

  • useEffect: This is the hook provided by React to perform side effects in functional components.
  • () => { /* Side effect code */ }: This is the function that contains the code for the side effect. It will run after the component renders. The function can return a cleanup function (optional), which will be executed before the component unmounts or before the next useEffect execution.
  • [dependencies]: This is an optional array of dependencies. If provided, the effect will only re-run if any of the dependencies have changed between renders. If no dependencies are provided ([]), the effect will only run once.

This can be used to cover many use cases.

Example 1: loading data from a server

Checkout this simple example where you can see a GitHub users details:

👇Enter your Github handle

Loading...

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

const GithubProfile = ({ username }) => {
  const [profileData, setProfileData] = useState(null);

  useEffect(() => {
    const fetchProfile = async () => {
      try {
        const response = await fetch(`https://api.github.com/users/${username}`);
        const data = await response.json();
        setProfileData(data);
      } catch (error) {
        console.error("Error fetching GitHub profile:", error);
      }
    };

    fetchProfile();
// depends on username. 
// the effect will run each time it changes
  }, [username]);

  return (
    <div>
      {profileData ? (
        <div>
          <h2>{profileData.login}</h2>
          <img src={profileData.avatar_url} alt={`${profileData.login}'s avatar`} />
          <p>{profileData.bio}</p>
        </div>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
};
export default GithubProfile;

It can be used Like follows in your app:

import React ,{ useState }from "react";
import GithubProfile from "./GithubProfile";

const App = () => {
  const [userName,setUserName]=useState("youssefbenlemlih");

  return (
    <div>
      <h1>GitHub Profile Viewer</h1>
        <input
          type={"text"}
          value={userName}
          onChange={(e) => setUserName(e.target.value)}
        />
      <GithubProfile username={userName} />
    </div>
  );
};

export default App;

Now each time the user name changes, the effect function will be called and the new information will be shown.

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

const ShowWindowWidth = () => {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => {
      setWidth(window.innerWidth);
    };
    // Add event listener when the component mounts
    window.addEventListener('resize', handleResize);

    // Cleanup function to remove the event listener when the component unmounts
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // The empty dependency array ensures that this effect runs only once, similar to componentDidMount

  return (
    <div>
      <p>Window Width: {width}</p>
    </div>
  );
};

export default ShowWindowWidth;

Explain

Attention: in dev mode in react strict mode, react will run your effect and cleanup twice, to make it obvious when you don’t provide a correct cleanup function (link external blog of tweet)