React JS Tutorial: `useEffect` (with cleanup, dependencies)

beginner
13 min

React JS Tutorial: useEffect (with cleanup, dependencies)

Welcome back to CodeYourCraft! Today, we're diving deep into the world of React JS, exploring one of its most powerful hooks: useEffect. By the end of this lesson, you'll have a solid understanding of useEffect, including cleanup functions, dependencies, and practical examples. Let's get started! šŸŽÆ

What is useEffect?

useEffect is a built-in React hook that allows us to perform side effects in function components. It gets called after render and is used for:

  • Fetching data from APIs
  • Updating the document title
  • Manipulating the DOM
  • And more! šŸ“

Let's dive into the structure of useEffect and see how it works.

The Basics of useEffect

useEffect accepts a function as its first argument, which contains the code to be executed after render. This function is called as a side effect. Here's an example:

jsx
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }

In this example, we're using the useState hook to manage state and the useEffect hook to update the document title whenever the count changes.

Cleanup Functions

You might have noticed that we don't return anything from the useEffect function in our example. But what if we want to perform cleanup actions? For example, we might need to cancel a fetch request or clear a timeout.

For that, we can return a cleanup function:

jsx
import React, { useState, useEffect } from 'react'; function Timer() { const [timer, setTimer] = useState(0); const intervalId = React.useRef(); useEffect(() => { function tick() { setTimer(timer + 1); } intervalId.current = setInterval(tick, 1000); return () => { clearInterval(intervalId.current); }; }, []); return <div>{timer}</div>; }

In this example, we're setting up an interval that updates the timer every second. When the component unmounts, the cleanup function is called, and the interval is cleared.

Dependencies

So far, we've seen useEffect without dependencies. But what if we want to trigger the effect only when certain values change? We can pass an array of dependencies as the second argument to useEffect.

jsx
import React, { useState, useEffect } from 'react'; function SearchResults({ searchTerm }) { const [results, setResults] = useState([]); useEffect(() => { // Fetch data based on searchTerm fetch(`https://api.example.com/search?q=${searchTerm}`) .then((response) => response.json()) .then((data) => setResults(data)); }, [searchTerm]); return <div>{results.map((result) => <div key={result.id}>{result.title}</div>)}</div>; }

In this example, we're fetching data based on the searchTerm prop. But we don't want to fetch data every time the component renders; instead, we want to fetch data only when searchTerm changes. That's why we're passing searchTerm as the second argument to useEffect.

Quick Quiz
Question 1 of 1

What is the purpose of the second argument in `useEffect`?

Conclusion

In this lesson, we've explored the useEffect hook in depth, learning about cleanup functions and dependencies. You're now ready to use useEffect in your own projects to perform side effects and manage state more effectively.

Stay tuned for more React JS tutorials here at CodeYourCraft, where we continue to help you level up your coding skills! šŸ’”

šŸ“ Note: Remember to clean up any resources when a component unmounts to avoid memory leaks.

šŸ“ Note: The types for useEffect are: useEffect(effect: (...args: any[]) => void, deps: any[] | undefined)

šŸ“ Note: In React 18, useEffect will receive a new third argument: deps2, which will work similar to the existing deps array but with some improvements. Stay tuned for more updates! šŸŽÆ

Happy coding! šŸ¤–šŸ’»šŸš€