1
- import { useState , useContext , useEffect } from 'react' ;
1
+ import { useState , useContext , useEffect , useRef } from 'react' ;
2
2
import { NavigationContext } from '@react-navigation/core' ;
3
3
4
4
export function useNavigation ( ) {
@@ -19,27 +19,29 @@ export function useNavigationKey() {
19
19
20
20
export function useNavigationEvents ( handleEvt ) {
21
21
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
+ } ) ;
22
27
useEffect (
23
28
( ) => {
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 ) ;
35
34
} ;
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 ( ) ) ;
36
43
} ,
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]
43
45
) ;
44
46
}
45
47
0 commit comments