React’s useEffect
hook is a built-in hook that allows you to run side effects (such as fetching data or subscribing to events) in your functional components. A side effect is any code that runs outside of the component’s render function, and is used to update the component’s state, perform an action, or interact with the browser.
useEffect
is a hook that takes two arguments: the first is a function that contains the side effect code, and the second is an array of dependencies. The hook will run the function after the component has rendered, and will only run it again if any of the dependencies have changed.
Here’s an example of how you might use useEffect
in a component:
import { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos/')
.then(response => response.json())
.then(data => setData(data));
}, []);
return (
<>
<p>Data:</p>
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
</>
);
}
In this example, the component fetches a list of todos from an API after the component has rendered. The fetching will happen only once when the component first rendered because the dependency array passed to the useEffect hook is empty, this means that the effect doesn’t depend on any state or props, it runs only once.
It’s important to note that the second argument to useEffect
should be a list of variables that you want to track for changes. If you don’t pass a second argument or if you pass an empty array, useEffect
will only run once when the component mounts.
You can also use useEffect
to handle cleanup logic, by returning a function from the callback passed to useEffect
. This function will be called right before the effect is re-ran.
import { useState, useEffect } from 'react';
function MyComponent({userId}) {
const [data, setData] = useState([]);
useEffect(() => {
const subscription = fetch(`https://jsonplaceholder.typicode.com/todos/${userId}`)
.then(response => response.json())
.then(data => setData(data));
return () => {
// cleanup logic
subscription.unsubscribe();
}
}, [userId]);
return (
<>
<p>Data:</p>
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
</>
);
}
In this example, the component fetches a list of todos based on the userId prop, and the effect only re-runs when the userId prop changes. also, it unsubscribes from the data source when the component unmounts or the userId changes.
here are a few more examples of how you might use the useEffect
hook in different scenarios:
Table of Contents
Handling componentDidMount and componentWillUnmount
import { useState, useEffect } from 'react';
function MyComponent() {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
return () => {
setIsMounted(false);
}
}, []);
return (
<>
{isMounted ? <p>Component is mounted</p> : <p>Component is unmounted</p>}
</>
);
}
In this example, the component sets the isMounted
state to true when it first renders, and sets it to false when it unmounts. This can be used to mimic the behavior of the componentDidMount
and componentWillUnmount
lifecycle methods.
Handling window resize
import { useState, useEffect } from 'react';
function MyComponent() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
setWindowWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
}
}, []);
return (
<>
<p>Window width: {windowWidth}</p>
</>
);
}
In this example, the component updates the windowWidth
state when the window is resized. It uses the useEffect
hook to add and remove an event listener for the resize
event.
Handling form input
import { useState, useEffect } from 'react';
function MyComponent() {
const [formData, setFormData] = useState({});
useEffect(() => {
console.log(formData);
}, [formData]);
return (
<>
<form>
<label>
Name:
<input type="text" name="name" onChange={e => setFormData({...formData, name: e.target.value})} />
</label>
<br />
<label>
Email:
<input type="email" name="email" onChange={e => setFormData({...formData, email: e.target.value})} />
</label>
</form>
</>
);
}
In this example, the component uses the useEffect
hook to log the current form data to the console every time the form data changes. It uses the useState
hook to store the form data in a state variable, and updates it when the form inputs are changed.
These are just a few examples of the many ways you can use the useEffect
hook to handle side effects in your React components. With this hook, you can handle a wide variety of tasks, such as fetching data, handling browser events, and updating the component’s state based on changes in props or other
In summary, useEffect
is a powerful