DEV Community

Cover image for React's useEffect Hook
Maasa Kono
Maasa Kono

Posted on

React's useEffect Hook

One of the built-in hooks in React is the useEffect hook. This is a function that runs upon every rendering of a component, starting from the initial rendering when the component first loads to any changes to the component's state. This can be useful for tasks like fetching data or manipulating the DOM, amongst other things.

Note: There will be references to the useState hook here, so if a quick review would be helpful, you can check out my prior blog on useState. I will also put a link at the end for The Net Ninja's tutorial video on this topic as well.


In order to begin using the useEffect hook, we will need to first import it from the React library into the component at the top:

import { useState, useEffect } from 'react';
Enter fullscreen mode Exit fullscreen mode

And now we can use this hook somewhere above the return statement. Since this function won't return anything to us, we will not be storing it in a variable.

const SomeComponent = () => {
  useEffect(() => {
    console.log('useEffect hook just ran because this component rendered');

  return (
    // Whatever this component is returning
Enter fullscreen mode Exit fullscreen mode

Avoid the Endless Render-Loop

Beware of changing state inside the useEffect hook because we could end up in an endless render-loop.

Here is a step-by-step of what would happen if we include a function that changes state inside useEffect:

  1. Initial render of the component occurs
  2. useEffect is triggered
  3. State is updated
  4. Component re-renders due to change in state
  5. The re-render triggers useEffect again
  6. Back to #3, and so on and so forth...

We can remedy this issue by passing in a dependency array as a second argument to the useEffect hook.

If we pass in an empty (dependency) array as a second argument to useEffect, this function will only run after the initial render, and it won't be triggered even if the component's state changes.

  useEffect(() => {
    console.log('useEffect hook ran on initial render of the component, but no more!');
  }, [] // All we're doing is adding this empty array here);
Enter fullscreen mode Exit fullscreen mode

Now, let's say we want useEffect to run at the initial render and only whenever a certain value (meaning, a specific property of state) changes. We can pass the reference to that value inside the dependency array (so there can be multiple ones), and useEffect will now know to watch that state, only triggering if any changes are made to that specific state value.

Here is what it could look like if we have a component with a useEffect hook that only gets triggered when there's any change made to its number state, ignoring any other state changes:

const ExampleComponent = () => {
  // We are setting the initial state of `letter` and `number` using the useState hook
  const [letter, setLetter] = useState('A');
  const [number, setNumber] = useState(1);

  useEffect(() => {
    // We are logging this message to the console only at the first render of this component and when the `number` value changes
    console.log('useEffect only runs at initial render and when the `number` state changes/updates');
  // useEffect knows to watch for changes in the `number` value because we are passing it as a second argument here as a dependency 
  }, [number]);

  return (
      // This button changes the `letter` state from `A` to `B`, but will not result in a trigger of useEffect
      <button onClick={() => setLetter('B')}>Will Not Trigger useEffect</button>
      // This button WILL trigger the useEffect hook because it is effecting the state change we are specifically listening for
      <button onClick={() => setNumber(number + 1)}>Will Trigger useEffect</button>
Enter fullscreen mode Exit fullscreen mode

Thanks for reading, and Happy Coding! 😄

Helpful Links

React's documentation on the useEffect Hook

The Net Ninja's tutorial going over the useEffect Hook

The Net Ninja's tutorial on the useState Hook

Discussion (0)