-
Notifications
You must be signed in to change notification settings - Fork 35
useNavigationEvents do not update listeners across re-renders #6
Comments
Note your implementation using [key] was probably causing troubles because the listener that gets called is the initial arrow function, and does not update as component re-render. The closure might catch variables and change behavior other time. function MyComp(({someBool})) {
useNavigationEvents(evt => {
if ( someBool ) {
alert("true");
}
else {
alert("false");
}
});
...
} If somebool goes from true to false, the behavior of the closure (which has captured the boolean state) change other time. It will keep alerting the initial boolean value, regardless of its current value. |
Hey Sébastien, sorry for the delayed response! I think it would make sense to only subscribe or re-subscribe when the key changes. I had attempted to do this by providing Can you help debug and fix this? |
Yes sure I can try to make a PR soon. Do you have any idea how I could reproduce your "pretty bad bug" caused by providing navigation key? Just to make sure I clear it |
I've tried running your dev web server. For unknown reasons I'm unable to yarn link my local react-navigation-hooks correctly. What's your dev setup for this project? I'm able to edit my local package from npm which is not ideal. The problem you met is:
On first render, the event list is empty. The closure capture events = [], and only the first render closure is registered to the event system, you basically, you keep adding the last event to an empty list, because the empty list was captured in the initial closure, and the list does not grow |
Hi @ericvicenti I've made a PR which permit to use a stable callback and only update the subscriptions on key change, and yet avoid the problems mentionned above. Note that with previous implementation (with no useEffect inputs) or with my fix, I still have weird bugs where the navigation listener stops firing after a few events. If I switch from docA to docB it works (I get action events), but as soon as I click to the focused doc again, I get "willBlur/didBlur" events, and then, the listener provided to navigation.addListener never fires again. Any idea what could be happening? |
Also want to point out that the closure the user provide may fire multiple times synchronously, so you want to do this: const [events, setEvents] = useState([]);
useNavigationEvents(evt => {
setEvents(evts => evts.concat(evt));
}); Instead of this: const [events, setEvents] = useState([]);
useNavigationEvents(evt => {
setEvents([...events,evt]);
}); With the later, of you get willBlur/didBlur firing synchronously, you will get the same closure problem and only capture the last event, because setState is not synchronous |
Will be fixed by #38, going to merge/release soon |
should be fixed by release 1.0.3 and #38, please tell me if everything works |
Hi,
I just want to warn that this implementation is problematic:
The key is needed, otherwise the events will be removed/added on every update.
Unfortunately when you add a didFocus listener on a focused view, the listener will fire immediately after adding (async), which has lead to an infinite loop on this issue: react-navigation/react-navigation#5058
I suggest as a solution to:
I can try to provide an implementation if you want
The text was updated successfully, but these errors were encountered: