From 3e075bbfc2965ff586ba9b1f1289cbb7c88be7f3 Mon Sep 17 00:00:00 2001 From: slorber Date: Sun, 18 Nov 2018 19:54:07 +0100 Subject: [PATCH 1/2] fix #6 --- src/Hooks.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Hooks.js b/src/Hooks.js index 741474d..4905aa4 100644 --- a/src/Hooks.js +++ b/src/Hooks.js @@ -1,4 +1,4 @@ -import { useState, useContext, useEffect } from 'react'; +import { useState, useContext, useEffect, useRef } from 'react'; import { NavigationContext } from '@react-navigation/core'; export function useNavigation() { @@ -19,27 +19,29 @@ export function useNavigationKey() { export function useNavigationEvents(handleEvt) { const navigation = useNavigation(); + const currentListenerRef = useRef(handleEvt); + // We want to make sure to run the last closure/listener provided by the user + useEffect(() => { + currentListenerRef.current = handleEvt; + }); 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(); + // We pass a stable listener to react-navigation event system, it will only change on state key change + // We use a ref inside this listener to make sure we execute the last closure provided by the user + // See https://github.com/react-navigation/react-navigation-hooks/issues/6#issuecomment-439713309 + const stableListener = (...args) => { + currentListenerRef.current(...args); }; + const subs = [ + navigation.addListener('action', stableListener), + navigation.addListener('willFocus', stableListener), + navigation.addListener('didFocus', stableListener), + navigation.addListener('willBlur', stableListener), + navigation.addListener('didBlur', stableListener), + ]; + return () => subs.forEach(sub => sub.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] + //[navigation.state.key] ); } From 0842db383db416b8d8c01d323d1ac392ad5a2c1c Mon Sep 17 00:00:00 2001 From: slorber Date: Sun, 18 Nov 2018 19:55:20 +0100 Subject: [PATCH 2/2] typo --- src/Hooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hooks.js b/src/Hooks.js index 4905aa4..3e150c3 100644 --- a/src/Hooks.js +++ b/src/Hooks.js @@ -41,7 +41,7 @@ export function useNavigationEvents(handleEvt) { ]; return () => subs.forEach(sub => sub.remove()); }, - //[navigation.state.key] + [navigation.state.key] ); }