Skip to content

Commit 3e075bb

Browse files
committed
1 parent 092e7ab commit 3e075bb

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

src/Hooks.js

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useContext, useEffect } from 'react';
1+
import { useState, useContext, useEffect, useRef } from 'react';
22
import { NavigationContext } from '@react-navigation/core';
33

44
export function useNavigation() {
@@ -19,27 +19,29 @@ export function useNavigationKey() {
1919

2020
export function useNavigationEvents(handleEvt) {
2121
const navigation = useNavigation();
22+
const currentListenerRef = useRef(handleEvt);
23+
// We want to make sure to run the last closure/listener provided by the user
24+
useEffect(() => {
25+
currentListenerRef.current = handleEvt;
26+
});
2227
useEffect(
2328
() => {
24-
const subsA = navigation.addListener('action', handleEvt);
25-
const subsWF = navigation.addListener('willFocus', handleEvt);
26-
const subsDF = navigation.addListener('didFocus', handleEvt);
27-
const subsWB = navigation.addListener('willBlur', handleEvt);
28-
const subsDB = navigation.addListener('didBlur', handleEvt);
29-
return () => {
30-
subsA.remove();
31-
subsWF.remove();
32-
subsDF.remove();
33-
subsWB.remove();
34-
subsDB.remove();
29+
// We pass a stable listener to react-navigation event system, it will only change on state key change
30+
// We use a ref inside this listener to make sure we execute the last closure provided by the user
31+
// See https://github.com/react-navigation/react-navigation-hooks/issues/6#issuecomment-439713309
32+
const stableListener = (...args) => {
33+
currentListenerRef.current(...args);
3534
};
35+
const subs = [
36+
navigation.addListener('action', stableListener),
37+
navigation.addListener('willFocus', stableListener),
38+
navigation.addListener('didFocus', stableListener),
39+
navigation.addListener('willBlur', stableListener),
40+
navigation.addListener('didBlur', stableListener),
41+
];
42+
return () => subs.forEach(sub => sub.remove());
3643
},
37-
// For TODO consideration: If the events are tied to the navigation object and the key
38-
// identifies the nav object, then we should probably pass [navigation.state.key] here, to
39-
// make sure react doesn't needlessly detach and re-attach this effect. In practice this
40-
// seems to cause troubles
41-
undefined
42-
// [navigation.state.key]
44+
//[navigation.state.key]
4345
);
4446
}
4547

0 commit comments

Comments
 (0)