Skip to content
This repository was archived by the owner on Aug 8, 2024. It is now read-only.
This repository was archived by the owner on Aug 8, 2024. It is now read-only.

On will/didFocus subscribe, stop firing the listener if current screen is focused #72

@slorber

Description

@slorber

Hi,

Today, when we add a will/didFocus listener on a screen, if that screen is currently focused, the listener will fire.

I think that behavior was implemented at a time where navigation.isFocused() and withNavigationFocus didn't exist yet, does not make sense anymore and is complicating the library usage.

For example, it makes it impossible to unsubscribe/resubscribe the same listener (or eventually closure/arrow function) without any side effect, which complicates the implementation of consuming code which need to ensure to register "stable listeners"

Also, one major usecase for navigation events is to refresh the screen data on focus.
The problem is that we use data loading systems that may already perform a fetch on mount (react-apollo, react-refetch...), so wiring onWillFocus={() => refetch()} will actually trigger a duplicate fetch on mount.
As mentionned during the implementation of <NavigationEvents /> here, I solved this problem on my app with this kind of code:

handleWillFocus = (() => {
    let count = 0;
    return payload => {
            if ( payload.action.type === NavigationActions.BACK ) {
              return; // We don't want to refresh on back so that user does not loose pagination state
            }
            if ( count > 0 ) {
              this.refreshTabData()
            }
           count++;
    }
  })();

Removing the willFocus event after subscribe will solve that problem for all people that are trying to refetch on screen focus. If the behavior is intended it can still added back in componentDidMount anyway.


This is a breaking change and users should perform these migrations:

  1. If user wants to fire something on mount if the screen is focused, he can implement that with navigation.isFocused() in componentDidMount

  2. If user wants to track focused state, he can use withNavigationFocus (also implemented later) or init his state with navigation.isFocused()


If this is validated I'd be happy to send a PR to all the concerned projects of the system (core, NavigationEvents, hooks)

Metadata

Metadata

Assignees

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