Avoid adding unnecessary dependencies to useEffect

Viewed 197

I am using react table in my app with server side pagination with search. Whenever pagination changes I use onPaginationChange prop to call API. But I also have a search input text. For this I use useEffect to listen to search text changes and call API.

<Pagination 
    onPaginationChange={(pageSize, pageNo) => {
        setNoOfRecords(pageSize);
        dispatchGet(
            dispatch,
            currentOrg.id,
            pageSize,
            pageNo,
            searchText,
        );
    }} //this is ok
/>

I also have a searchText state and useEffect for searchText change and API call:

const [searchText, setSearchText] = useState("");
useEffect(() => {
    if (currentOrg) {
        dispatchGetSubOrgs(
            dispatch,
            currentOrg.id,
            noOfRecords,
            currentPage, // I get these from redux store and get updated when API calls
            searchText,
        );
    }
}, [searchText]);

Here Eslint complains that I need to add currentPage to dependency array. But if I add it and onPaginationChange gets called due to some pagination changes, currentPage will be updated and useEffect gets called and will call the API twice.

If I ignore this Eslint error, will it be a problem? Also, I don't know why React wants me to add everything in dependency array. What if I don't want theuseEffect to run when something in the dependency array changes? I'm forced to add it because it might have stale values. How do I deal with this?

2 Answers

For useEffect, here is the mindset in simplistic way: "Every variable that might change, that's defined outside and my callback function uses, needs to be in my dependency array, so I know when I ask the callback to execute again".

But you as developer can make your own choices about what should be in that array. You can even turn off those warnings with the help of eslint-disable-next-line react-hooks/exhaustive-deps, like so:

 useEffect(() => {
    if (currentOrg) {
      dispatchGetSubOrgs(
        dispatch,
        currentOrg.id,
        noOfRecords,
        currentPage,
        searchText,
      );
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchText]

But doing so systematically might create bugs in the futur, as you loose those warnings. And normally, there is always a recommended workaround rather than turning them off.

you can add the following comments at the end of the code

       if (currentOrg) {
         dispatchGetSubOrgs(
           dispatch,
           currentOrg.id,
           noOfRecords,
           currentPage, 
           searchText,
         );
       }
   // eslint-disable-next-line react-hooks/exhaustive-deps    
     }, [searchText]

Related