Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

useEffect loop due to useSelector updating

I have a useEffect

function Component () {
    const facets = useSelector(getFacets)

    useEffect(() => {
        dispatch(search(facets, param2, param3))
    }, [dispatch, facets, param2, param3])
    
    //rest of component with return
}

now search will actually update that facets

//Inside my slice
const search = (facets, param2, param3) => async(dispatch) => {
   //do a fetch using param2 and param3
   //fetch comes back with a facets object
   //alter response facets object based on 'old' facets
   dispatch(setFacets(newFacets)) // set the new facets
}

The issue is, when this useEffect runs, the re-render causes const facets = useSelector(getFacets) to load a new value... Linting requires I have facets as a dependency in the useEffect but putting it there means it'll just loop over and over again. How do I stop it?

I've tried pulling the logic out of a useEffect and putting it in a useCallback, but again, linting requires that I put facets as a dependency, which is basically the same exact issue.

like image 270
James B Avatar asked Nov 06 '25 12:11

James B


1 Answers

Solved


Sooooo Redux has a few store methods; dispatch being one of them. For me, the store method I was looking for was getState. More info if you look here and cmd/ctrl + F 'getState'

I didn't think I could access the state within my slice because React would not allow me to use useSelector within the slice for obvious reasons. What was not obvious to me at the time was that I could gain access with getState

So, the edited code would look like:

  1. remove the facets param within the component because I won't need it anymore
function Component () {
    //const facets = useSelector(getFacets) --> NO LONGER NEEDED

    useEffect(() => {
        dispatch(search(/*facets, */param2, param3))
    }, [dispatch, /*facets, */param2, param3])
    
    //rest of component with return
}
  1. edit the function within the slice, removing the facets param and including getState alongside dispatch
//Inside my slice
const search = (param2, param3) => async(dispatch, getState) => {
   //do a fetch using param2 and param3
   //fetch comes back with a facets object
   //grab 'old' facets using NEW getState and same selector: getFacets
   oldFacets = getFacets(getState())
   //alter response facets object based on oldFacets
   dispatch(setFacets(newFacets)) // set the new facets
}

Voila, no more infinite loop.

like image 85
James B Avatar answered Nov 09 '25 10:11

James B



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!