Reputation: 14385
I am trying to useFocusEffect
to rerender a component in my view when I focus the view.
I did:
const [theKey, setTheKey] = useState(0);
Then:
useFocusEffect(() => { setTheKey(theKey + 1) }, [theKey]);
And the jsx:
<SwipeListView key={theKey} />
It does not work well, I have the errror: Maximum update depth exceeded
Can someone share a way to rerender it?
I do not have this issue with react router.
Upvotes: 2
Views: 3188
Reputation: 115
I also encountered issue with useFocusEffect. Either it triggers infinite loop / render, or it keeps a stale version of the function.
const [count, setCount] = useState(1);
const doSomething = useCallback(() => {
console.log(count);
setCount(count + 1);
}, [count]);
useFocusEffect(
useCallback(() => {
doSomething(); // Count will always be 1 (cached value)
}, [doSomething])
);
useFocusEffect(
useCallback(() => {
doSomething(); // Latest count, but infinite loop due to doSomething() is recreated when count changes
}, [doSomething])
);
Instead, can try with the combination of useIsFocus and usePrevious which works well with existing useEffect method.
import { useIsFocused } from "@react-navigation/native";
import { useEffect, useRef } from "react";
// usePrevious custom hook
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const isFocused = useIsFocused();
const prevIsFocused = usePrevious(isFocused);
useEffect(() => {
if (!prevIsFocused && isFocused) {
// Run your code here
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocused]);
Upvotes: 0
Reputation: 2187
Issue is here:
useFocusEffect(() => { setTheKey(theKey + 1) }, [theKey]);
Inside this function you update theKey
. And each time theKey
gets updated the effect gets called again. This results in an infinite loop.
There are 2 solutions:
Remove theKey dependency:
useFocusEffect(
() => { setTheKey(theKey + 1) },
["replace with something else"]
);
Add a condition before updating the state:
useFocusEffect(
() => { if ("some condition") setTheKey(theKey + 1) },
[theKey]
);
This will prevent the infinite loop.
Upvotes: 1