What is useEffect in React?
useEffect is one of the most powerful and commonly used hooks in React. It allows you to perform side effects in functional components.
- Side effects can include:
- Data fetching
- Subscribing to events
- Manually manipulating the DOM
- Working with timers and intervals
useEffect runs after the render phase of the component, ensuring your component has already rendered and is ready to handle side effects.
Basic Syntax
useEffect(() => {
// Your side effect code here
});
However, there is much more to useEffect than this simple syntax. Let's go through different scenarios to understand its full functionality.
Example Scenario: Fetching User Data
Let say we have a scenario where we want to fetch user data when the component mounts.
Step 1: Import useEffect and useState
import React, { useState, useEffect } from 'react';
Step 2: Basic Usage (Component Mounting)
const UserProfile = () => {
const [userData, setUserData] = useState(null);
useEffect(() => {
// Fetch user data when the component mounts
fetch('https://jsonplaceholder.typicode.com/users/1')
.then(response => response.json())
.then(data => setUserData(data))
.catch(error => console.error('Error fetching data:', error));
}, []); // Empty dependency array means it runs only on mount
if (!userData) return <div>Loading...</div>;
return (
<div>
<h1>{userData.name}</h1>
<p>Email: {userData.email}</p>
<p>Phone: {userData.phone}</p>
</div>
);
};
Explanation:
- In this example, useEffect is triggered once, after the component is first rendered. The [] dependency array ensures that the effect runs only when the component mounts.
- We fetch user data and update the state using setUserData.
Step 3: Running Effects on Every Render
If you omit the dependency array, the effect will run after every render:
useEffect(() => {
console.log('Component rendered or re-rendered');
});
Note: Use this approach cautiously as it can lead to performance issues.
Step 4: Using Dependencies
Often, you want to re-run your effect when specific variables change. You can achieve this by adding dependencies to the array.
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // Runs the effect only when `count` changes
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
Explanation:
The effect will run whenever the count state changes.
Step 5: Cleanup Function
Some effects, like event listeners or timers, need to be cleaned up when the component unmounts or before running the effect again. You can return a cleanup function from useEffect.
useEffect(() => {
const timer = setInterval(() => {
console.log('Interval running');
}, 1000);
return () => {
clearInterval(timer); // Cleanup when the component unmounts
};
}, []);
Explanation:
This effect sets an interval when the component mounts, but clears the interval when the component unmounts to prevent memory leaks.
Step 6: Multiple useEffect Calls
You can have multiple useEffect calls in a component for handling different side effects.
useEffect(() => {
console.log('Fetching data');
// data fetching code
}, []);
useEffect(() => {
console.log('Setting up event listeners');
// event listener setup code
}, []);
Full Example: Fetching and Updating User Data Based on User ID
import React, { useState, useEffect } from 'react';
const UserProfile = () => {
const [userId, setUserId] = useState(1);
const [userData, setUserData] = useState(null);
useEffect(() => {
// Fetch user data when userId changes
fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
.then(response => response.json())
.then(data => setUserData(data))
.catch(error => console.error('Error fetching data:', error));
}, [userId]); // Effect runs when userId changes
const nextUser = () => setUserId(userId + 1);
if (!userData) return <div>Loading...</div>;
return (
<div>
<h1>{userData.name}</h1>
<p>Email: {userData.email}</p>
<p>Phone: {userData.phone}</p>
<button onClick={nextUser}>Next User</button>
</div>
);
};
export default UserProfile;
Explanation:
The user data fetches and updates every time userId changes. We also provide a button to increment the user ID.
Conclusion
useEffect is a versatile and essential hook in React that lets you manage side effects within functional components. By understanding how to use dependency arrays and cleanup functions, you can effectively manage data fetching, event listeners, and more.
You can now start experimenting with useEffect to create efficient React components!
317 views