React hooks lets you use state and life cycle features from functional components and Its been popular among the react developers community since its advent in react version 16.8.
So useEffect is generally used for performing some side effects like fetching data asynchronously, adding event listeners and cleaning up some resources. So let's see the ways how we can use them:
1) By Making the network calls and updating the component state
you can limit the number of times useEffects gets invoked by providing the dependency array which means only executes when this value has changed.
eg. Implementing the pagination logic in lazy loading, fetching data when the user scrolls to the bottom of the page.
useEffect(() => {
fetchData(page).then((results)=>{
// updating the component state which will result in re-rendering the component
})
},[page])
2)Setting up some event listeners and implementing debounce logic
Suppose the user is typing something into the search box and hit the API call when the user stops typing for a certain number of milliseconds.. this avoids redundant API calls thus performance optimization.
It's also important to clear the previously registered timer using the cleanup method to avoid getting inconsistent behaviour.
useEffect(() => {
const timerId = setTimeout(()=>{
onSearchChange(value);
},500);
return () => clearTimeout(timerId)
},[])
3) Cleaning up the resources while unmounting the component
React useEffect hook cleanup method can be effective in cleaning the resources allocated and cancelling unnecessary network calls.
eg. Logging the usage time of the user that someone spends on this page(see below snippets)
Remember to put an empty dependency array[] for this purpose otherwise cleanup function will be executed each time before the component is re-rendered.
And the values used inside the cleanup form the closure within the useEffect block and if you try to access the state value, So you will get the previous state value inside the cleanup, not the latest one which is updated just now.
useEffect(() => {
const startTime=new Date().getTime();
return () => {
const timespent = parseInt((new Date().getTime() - startTime) / (1000 * 60)); // in minutes
// now you can sent this to mixpanel dashboard for tracking purpose
}
},[])
4) Performance Optimization using the useMemo hook
Along with the useMemo hook to memoize the values, It can be used for performance optimization by avoiding the re-computation of the heavy computing task and thus reducing the number of execution for useEffect hook.
// this will be computed only when id changes otherwise cached results will be provided.
const memoizedValue =useMemo(() => computeSomething(),[props.id]);
useEffect(() => {
// this code will be executed only when `memoizedValue` value has been changed
},[memoizedValue])
5) Implementing the custom hook
Implementing the lazy loading in the list and the whole logic can be encapsulated in a separate re-usable custom hook component which will internally handle all its logic and in return give you the updated state values which you can use.
import { useEffect, useState } from "react";
import { handleGetRequest } from "../../helper/httpRequests";
export default function fetchUsersList( id, pageNumber, params = '') {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [usersList, setUsersList] = useState([]);
const [hasMore, setHasMore] = useState(true); // reflects if next page data exists or not -- updated from api response
// this will be executed when user scrolls to bottom of the page and page changes will trigger this or params when changed which are like the filters
useEffect(() => {
setLoading(true);
const options = {
page: pageNumber,
filter: params,
organisation: id
}
handleGetRequest('/fetch/users/', options)
.then(({ data }) => {
setUsersList((previoususersList) => {
return [...previoususersList, ...data.results]
});
setHasMore(data.next !== null);
setLoading(false);
setError(false)
})
.catch(() => {
setError(true);
setLoading(false)
});
}, [pageNumber, params]);
//resetting the previous list data because for new filter previous list data is garbage.
useEffect(() => {
setUsersList([]);
setHasMore(true);
}, [params])
return { loading, error, usersList, hasMore };
}
I have just listed the most common use cases of useEffect hook and there can be numerous other ways to use it.
If you have reached this far, If you found this post helpful please like and share this post and provide your valuable feedback/suggestions to this post.
That's all for this post!!