Intro to React useEffect Hook

An introduction on how to use useEffect Hook
What is a useEffect Hook?

TLDR

React useEffect is an alternative to the "old" class lifecycle methods/hooks.

It can be used to manage side effects, such as network requests, or to run a piece of code when the component is mounted, updated, or unmounted.

Longer version

Prior to React v16.8, we can only enable a component
to react to state changes using lifecycle methods.

How to define a useEffect
useEffect(() => { //(1) declaration
  // (2)effect
  return () => {
    // (3)cleanup 
  }
}, /* (4)dependency array */)
Here's an explanation of the above code:
  • We can declare an effect by calling either React.useEffect or useEffect
  • effect is the function that will be called when the component is mounted OR when the dependency array changes.
  • cleanup is the function that will be called when the effect "unmounted".
  • dependency array is the array of values that will be passed to the effect function.
    • If there is no dependency array, the effect will be called every time the component is mounted.
    • If the array is empty, the effect will be called only once when the component is mounted.
    • If the array is not empty, the effect will be called every time the component is mounted and the dependency array changes.
  • Examples
    Increment a counter every second until it reaches 10
    function App() {
      const [count, setCount] = useState(0)
    
      useEffect(() => {
        if (count < 10) {
          const interval = setInterval(() => {
            setCount(prev => prev + 1)
          }, 1000)
    
          // cleanup function
          return () => clearInterval(interval)
        }
      }, [count])
    
      // Render the component
    }
    Basic fetch from an API
    function App() {
      const [data, setData] = useState([])
    
      useEffect(() => {
        fetch('https://jsonplaceholder.typicode.com/users')
          .then(res => res.json())
          .then(data => setData(data))
      }, [])
    
      // Render the component
    }
    Fetching with loading indicator + error handling - then/catch/finally
    function App() {
      const [data, setData] = React.useState()
      const [error, setError] = React.useState()
      const [isLoading, setIsLoading] = React.useState(false)
    
      React.useEffect(() => {
        setIsLoading(true)
    
        fetchData()
          .then(data => {
            setError(null)
            setData(data)
          })
          .catch(data => {
            // handle error case anyway you want
            setError(data)
            setData(null)
          })
          .finally(() => setIsLoading(false))
      }, [])
    
      // Render the component
    }
    Fetching with loading indicator + error handling - async/await
    function App() {
      const [data, setData] = React.useState()
      const [error, setError] = React.useState()
      const [isLoading, setIsLoading] = React.useState(false)
    
      React.useEffect(() => {
        // yeah, this is weird
        (async () => {
          try {
            setIsLoading(true)
            const data = await fetchData()
            setError(null)
            setData(data)
          } catch(e) {
            // handle error case anyway you want
            setError(e)
            setData(null)
          }
          setIsLoading(false)
        })()
      }, [])
    
      // Render the component
    }
    Store a value in localStorage everytime the key or value changes
    function App({ name }) {
      const [value, setValue] = useState(() => localStorage.getItem(name))
    
      useEffect(() => {
        localStorage.setItem(name, value)
      }, [name, value])
      // Ignore old keys for now
    
      // Render the component
    }
    OR mimic a class lifecycle method

    Check this blog on how to convert a class lifecycle methods to useEffect hooks

    Additional Note
  • useEffect can only be used in functional components
  • The order of useEffect declarations are important.
  • useEffect in a custom hook is a great way to promote side effect reusability. I will discuss this in another blog.
  • Conclusion
    Compared to the old lifecycle methods, useEffect is much more powerful and flexible, making it an ideal choice when managing a side-effect.
    If you find it useful and you want to support me

    31

    This website collects cookies to deliver better user experience

    Intro to React useEffect Hook