I have a react native project. I am trying to pass in a variable object as a parameter between screens. I have it so that if the screen that has the passed in params senses that a parameter was detected, I want it to set the param object as the value of a useState constant.
I pass in the parameter using navigation.navigate like this:
const newFilter = {
home_type:selectedHomeTypes,
minPrice: min,
maxPrice: max,
bathsMin: bathCount,
bedsMin: bedCount,
sqftMin: sqftMin,
sqftMax: sqftMax,
}
navigation.navigate('HomeScreen', {newFilter: newFilter})
I have an if statement in the HomeScreen
that is supposed to detect if there is a route.params?.newFilter
It is sensing it and console logging the correct information in the function. The issue is that when it runs updateAppliedFilter()
and then setAppliedFilter()
I get an error that is an infinite loop issue.
Error:
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
childScreen:
const applyFilters = () => {
const newFilter = {
home_type:selectedHomeTypes,
minPrice: min,
maxPrice: max,
bathsMin: bathCount,
bedsMin: bedCount,
sqftMin: sqftMin,
sqftMax: sqftMax,
}
navigation.navigate('HomeScreen', {newFilter: newFilter})
}
ParentScreen:
const updateAppliedFilter = (filter) => {
setAppliedFilters(filter)
}
if(route.params?.newFilter){
console.log('filterFound')
console.log(route.params.newFilter)
updateAppliedFilter(route.params.newFilter)
}
When i do not run the setAppliedFilter
it works correctly and renders the console.logs
1 time. When I add the setAppliedFilter
, it goes into an infinite loop.
CodePudding user response:
If you navigate to ParentScreen
and provide newFilter
via the route.params
, then updateAppliedFilter
will be called inside the ParentScreen
and trigger a state change via setAppliedFilters
which will eventually rerender the screen. However, the route.params
do not change during this rerender (they will never be set to undefined), thus the updateAppliedFilter
function will be called again and again.
You can guard this using a useEffect
.
ParentScreen
React.useEffect(() => {
if (route.params?.newFilter) {
updateAppliedFilter(route.params.newFilter);
}
}, [route.params])