@@ -11,43 +11,30 @@ const EventNameToPropName = {
11
11
const EventNames = Object . keys ( EventNameToPropName ) ;
12
12
13
13
class NavigationEvents extends React . Component {
14
+ getPropListener = eventName => this . props [ EventNameToPropName [ eventName ] ] ;
15
+
14
16
componentDidMount ( ) {
15
17
this . subscriptions = { } ;
16
- EventNames . forEach ( this . addListener ) ;
17
- }
18
18
19
- componentDidUpdate ( prevProps ) {
19
+ // We register all navigation listeners on mount to ensure listener stability across re-render
20
+ // A former implementation was replacing (removing/adding) listeners on all update (if prop provided)
21
+ // but there were issues (see https://github.com/react-navigation/react-navigation/issues/5058)
20
22
EventNames . forEach ( eventName => {
21
- const listenerHasChanged =
22
- this . props [ EventNameToPropName [ eventName ] ] !==
23
- prevProps [ EventNameToPropName [ eventName ] ] ;
24
- if ( listenerHasChanged ) {
25
- this . removeListener ( eventName ) ;
26
- this . addListener ( eventName ) ;
27
- }
28
- } ) ;
29
- }
30
-
31
- componentWillUnmount ( ) {
32
- EventNames . forEach ( this . removeListener ) ;
33
- }
34
-
35
- addListener = eventName => {
36
- const listener = this . props [ EventNameToPropName [ eventName ] ] ;
37
- if ( listener ) {
38
23
this . subscriptions [ eventName ] = this . props . navigation . addListener (
39
24
eventName ,
40
- listener
25
+ ( ...args ) => {
26
+ const propListener = this . getPropListener ( eventName ) ;
27
+ return propListener && propListener ( ...args ) ;
28
+ }
41
29
) ;
42
- }
43
- } ;
30
+ } ) ;
31
+ }
44
32
45
- removeListener = eventName => {
46
- if ( this . subscriptions [ eventName ] ) {
33
+ componentWillUnmount ( ) {
34
+ EventNames . forEach ( eventName => {
47
35
this . subscriptions [ eventName ] . remove ( ) ;
48
- this . subscriptions [ eventName ] = undefined ;
49
- }
50
- } ;
36
+ } ) ;
37
+ }
51
38
52
39
render ( ) {
53
40
return null ;
0 commit comments