useEffect
?useEffect
hook allows you to perform side effects in your component, such as fetching data, subscribing to events, and manually changing the DOM.useEffect
The basic syntax of useEffect
is as follows:
useEffect(() => {
// Side effect code here
}, [dependencies]);
[]
), the effect runs only once when the component mounts.useEffect
to Fetch DataLet's create an example where we fetch data from an API when the component mounts.
import React, { useState, useEffect } from "react";
function FetchData() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("https://api.example.com/data")
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
})
.catch((error) => console.error(error));
}, []); // Empty array means effect runs once when the component mounts
return loading ? <p>Loading...</p> : <pre>{JSON.stringify(data, null, 2)}</pre>;
}
export default FetchData;
🔹 Explanation:
useEffect
is used to perform the fetching of data from an API when the component is mounted.[]
ensures that the effect runs only once when the component mounts.data
state and set loading
to false
once the data is fetched.useEffect
You can use useEffect
to modify the document title whenever a state changes.
import React, { useState, useEffect } from "react";
function TitleChanger() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]); // Effect runs whenever `count` changes
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default TitleChanger;
🔹 Explanation:
useEffect
to change the document title every time the count
state changes.[count]
means the effect will run whenever count
is updated.useEffect
useEffect
also allows you to clean up side effects, like unsubscribing from a data stream or clearing a timer. This is done by returning a cleanup function inside the useEffect
function.
import React, { useState, useEffect } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
// Cleanup function to clear the interval when the component unmounts
return () => clearInterval(timer);
}, []); // Effect runs once on mount and cleans up on unmount
return <p>Timer: {seconds} seconds</p>;
}
export default Timer;
🔹 Explanation:
useEffect
sets up an interval that increases the seconds
state every second.clearInterval(timer)
is returned inside useEffect
, which will be called when the component unmounts, cleaning up the interval.[]
ensures that the effect runs only once when the component mounts.Sometimes, you want to run the effect only when specific values change. You can achieve this by using dependencies.
import React, { useState, useEffect } from "react";
function SearchComponent() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
useEffect(() => {
if (query) {
fetch(`https://api.example.com/search?q=${query}`)
.then((response) => response.json())
.then((data) => setResults(data))
.catch((error) => console.error(error));
}
}, [query]); // Effect runs whenever `query` changes
return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
<ul>
{results.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
export default SearchComponent;
🔹 Explanation:
useEffect
only runs when the query
state changes.query
has a value, it triggers a fetch request and updates the results
state.query
is an empty string.useEffect
useEffect
runs after the component renders. This allows it to interact with the DOM.[dependency1, dependency2]
).useEffect
hooks in a single component for different purposes (e.g., one for data fetching, another for DOM manipulation).