DEV Community

vidhya murali
vidhya murali

Posted on

React useEffect Hook

The **useEffect **Hook allows you to perform side effects in your components.

Some examples of side effects are:

  • fetching data,
  • directly updating the DOM,
  • timers.

useEffect accepts two arguments. The second argument is optional.

useEffect(<function>, <dependency>)

Example:
Use setTimeout() to count 1 second after initial render

But wait!! It keeps counting even though it should only count once!

  • useEffect runs on every render. That means that when the count changes, a render happens, which then triggers another effect.
  • This is not what we want. There are several ways to control when side effects run.

We should always include the second parameter which accepts an array. We can optionally pass dependencies to useEffect in this array

So, to fix this issue, let's only run this effect on the initial render

Here is an example of a useEffect Hook that is dependent on a variable. If the count variable updates, the effect will run again:

import { useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

createRoot(document.getElementById('root')).render(
  <Counter />
);



Enter fullscreen mode Exit fullscreen mode

if there are multiple dependencies, they should be included in the useEffect dependency array.

Effect Cleanup

Some effects require cleanup to reduce memory leaks.

Timeouts, subscriptions, event listeners, and other effects that are no longer needed should be disposed.

We do this by including a return function at the end of the useEffect Hook

import { useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';

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

  useEffect(() => {
    let timer = setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);

    return () => clearTimeout(timer)
  }, []);

  return <h1>I've rendered {count} times!</h1>;
}

createRoot(document.getElementById('root')).render(
  <Timer />
);
Enter fullscreen mode Exit fullscreen mode

Note: To clear the timer, we had to name it.

Reference :https://www.w3schools.com/react/react_useeffect.asp

Top comments (1)

Collapse
 
karthick_07 profile image
Karthick (k)

Good explanation