DEV Community

Cover image for React UseEffect Best Practice
Shaban-Eissa
Shaban-Eissa

Posted on

React UseEffect Best Practice

In this post we will see different cases of useEffect

first, let's see useEffect without any dependency

import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [name, setName] = useState("");
  const [dark, setDark] = useState(false);

  const age = 23
  const user = { name, age };

  const buttonStyle = {
    backgroundColor: dark && "#000",
    color: dark && "#FFF"
  };

  const handleName = (e) => {
    setName(e.target.value);
  };

  const handleClick = () => {
    setDark((currDark) => !currDark);
  };

  useEffect(() => {
    console.log(user);
  });

  return (
    <div className="App">
      <input value={name} onChange={handleName} />
      <button style={buttonStyle} onClick={handleClick}>
        Toggle Theme
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

in this code, any change in any state will cause re-render and then useEffect run again and again, so let's see the result in console when code run

Image description

second, let's see useEffect with dependency array

import { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [name, setName] = useState("");
  const [dark, setDark] = useState(false);

  const age = 23
  const user = { name, age };

  const buttonStyle = {
    backgroundColor: dark && "#000",
    color: dark && "#FFF"
  };

  const handleName = (e) => {
    setName(e.target.value);
  };

  const handleClick = () => {
    setDark((currDark) => !currDark);
  };

  useEffect(() => {
    console.log(user);
  } , [user]);

  return (
    <div className="App">
      <input value={name} onChange={handleName} />
      <button style={buttonStyle} onClick={handleClick}>
        Toggle Theme
      </button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

in this code useEffect will run when any change occur in user, now we can see that user is object and every re-render user object will have different reference, i mean we don't have the same reference for user object everytime so when we click on button we can see that the effect run !!!!!!!!!
we make effect depend on user object only, but why effect happen when we click on button, the normal is effect happen only when the user object value change, and so the answer for why when click on button effect runs is that because different reference of object.

let's see the result of this code :
Image description

and to solve this problem we can replace dependency array of useEffect by [name , age], then now we avoided different reference of user object

so let's see the result now

Image description

that is what we need now

Image description

an alternative solution to that with same result, we can keep user object in dependency and using useMemo() on user object like this code

import { useEffect, useMemo, useState } from "react";
import "./styles.css";

export default function App() {
  const age = 23;
  const [name, setName] = useState("");
  const [dark, setDark] = useState(false);

  const user = useMemo(() => {
    return { name, age };
  }, [name, age]);

  const buttonStyle = {
    backgroundColor: dark && "#000",
    color: dark && "#FFF"
  };

  const handleName = (e) => {
    setName(e.target.value);
  };

  const handleClick = () => {
    setDark((currDark) => !currDark);
  };

  useEffect(() => {
    console.log(user);
  }, [user]);

  return (
    <div className="App">
      <input value={name} onChange={handleName} />
      <button style={buttonStyle} onClick={handleClick}>
        Toggle Theme
      </button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

with useMemo() the user object reference will change only if any change occurred in name or age, then useEffect will run only if any change occurred in name or age.

Image description

Top comments (0)