useEffect in reactjs
useEffect
is a hook in React that allows you to perform side effects in functional components. Side effects can include tasks like fetching data, manually changing the DOM, and setting up subscriptions or timers. It serves a similar purpose to lifecycle methods in class components such as componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Here’s a comprehensive guide on how to use useEffect
:
Basic Usage
Example: Running an Effect on Initial Render
import React, { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
console.log('Component mounted');
// You can perform initial side effects here, like fetching data
return () => {
console.log('Component unmounted');
// Cleanup code goes here (e.g., clearing timers or subscriptions)
};
}, []); // Empty dependency array means this effect runs once on mount and cleanup on unmount
return <div>Hello, world!</div>;
};
export default MyComponent;
In this example:
- The effect runs once after the initial render because the dependency array is empty.
- The cleanup function runs when the component unmounts.
Dependencies
Example: Running an Effect When Dependencies Change
import React, { useState, useEffect } from 'react';
const MyComponent = ({ prop }) => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Effect ran because prop or count changed');
return () => {
console.log('Cleanup when prop or count changes or component unmounts');
};
}, [prop, count]); // Effect runs when 'prop' or 'count' changes
return (
<div>
<p>Prop: {prop}</p>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default MyComponent;
In this example:
- The effect runs whenever
prop
orcount
changes. - The cleanup function runs before the effect re-runs due to changes in dependencies and when the component unmounts.
No Dependency Array
Example: Running an Effect on Every Render
import React, { useState, useEffect } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Effect runs on every render');
return () => {
console.log('Cleanup on every render');
};
}); // No dependency array, so effect runs on every render
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default MyComponent;
In this example:
- The effect runs on every render.
- The cleanup function also runs on every render before the new effect runs.
Conditional Effects
Example: Running an Effect Conditionally
import React, { useState, useEffect } from 'react';
const MyComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
if (count > 0) {
console.log('Effect runs when count is greater than 0');
}
return () => {
if (count > 0) {
console.log('Cleanup when count changes and was greater than 0');
}
};
}, [count]); // Effect runs when 'count' changes
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default MyComponent;
In this example:
- The effect runs only if
count
is greater than 0. - The cleanup function also checks if
count
was greater than 0 before running.
Fetching Data
Example: Fetching Data on Mount
import React, { useState, useEffect } from 'react';
const DataFetchingComponent = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};
fetchData();
}, []); // Empty dependency array, so fetch data on mount
if (loading) return <p>Loading...</p>;
if (!data) return <p>No data available</p>;
return <div>Data: {JSON.stringify(data)}</div>;
};
export default DataFetchingComponent;
In this example:
- Data is fetched once when the component mounts.
- The
loading
state is updated based on the fetch request's lifecycle.
Summary
useEffect
: Used to perform side effects in functional components.- Dependencies: The second argument is an array of dependencies. The effect runs when any dependency changes.
- Cleanup: The cleanup function runs before the effect re-runs and when the component unmounts.
- Scenarios: Fetching data, setting up subscriptions, timers, logging, or manual DOM operations.
useEffect
provides a powerful and flexible way to handle side effects in React functional components, mimicking the behavior of lifecycle methods in class components while leveraging React's declarative nature.