Skip to content
This repository was archived by the owner on Dec 3, 2022. It is now read-only.
This repository was archived by the owner on Dec 3, 2022. It is now read-only.

useNavigationEvents do not update listeners across re-renders #6

@slorber

Description

@slorber

Hi,

I just want to warn that this implementation is problematic:

export function useNavigationEvents(handleEvt) {
  const navigation = useNavigation();
  useEffect(
    () => {
      const subsA = navigation.addListener('action', handleEvt);
      const subsWF = navigation.addListener('willFocus', handleEvt);
      const subsDF = navigation.addListener('didFocus', handleEvt);
      const subsWB = navigation.addListener('willBlur', handleEvt);
      const subsDB = navigation.addListener('didBlur', handleEvt);
      return () => {
        subsA.remove();
        subsWF.remove();
        subsDF.remove();
        subsWB.remove();
        subsDB.remove();
      };
    },
    // For TODO consideration: If the events are tied to the navigation object and the key
    // identifies the nav object, then we should probably pass [navigation.state.key] here, to
    // make sure react doesn't needlessly detach and re-attach this effect. In practice this
    // seems to cause troubles
    undefined
    // [navigation.state.key]
  );
}

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:

  • store react-navigation listeners in a ref to make them stable
  • wire the user provided listeners to the stable listeners of the ref (so that user is still able to provide arrow functions/unstable listeners, and the latest provided version will be called, instead of the one provided on initial render)
  • only update react-navigation listeners on some specific conditions, like key change?

I can try to provide an implementation if you want

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions