Skip to content
This repository was archived by the owner on Feb 25, 2020. It is now read-only.

Commit 715228f

Browse files
committed
Fix NavigationEvents onDidFocus infinite loop by using a different implementation that register all listeners on mount
fix for react-navigation/react-navigation#5058
1 parent 4462b3b commit 715228f

File tree

2 files changed

+115
-200
lines changed

2 files changed

+115
-200
lines changed

src/views/NavigationEvents.js

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,30 @@ const EventNameToPropName = {
1111
const EventNames = Object.keys(EventNameToPropName);
1212

1313
class NavigationEvents extends React.Component {
14+
getPropListener = eventName => this.props[EventNameToPropName[eventName]];
15+
1416
componentDidMount() {
1517
this.subscriptions = {};
16-
EventNames.forEach(this.addListener);
17-
}
1818

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)
2022
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) {
3823
this.subscriptions[eventName] = this.props.navigation.addListener(
3924
eventName,
40-
listener
25+
(...args) => {
26+
const propListener = this.getPropListener(eventName);
27+
return propListener && propListener(...args);
28+
}
4129
);
42-
}
43-
};
30+
});
31+
}
4432

45-
removeListener = eventName => {
46-
if (this.subscriptions[eventName]) {
33+
componentWillUnmount() {
34+
EventNames.forEach(eventName => {
4735
this.subscriptions[eventName].remove();
48-
this.subscriptions[eventName] = undefined;
49-
}
50-
};
36+
});
37+
}
5138

5239
render() {
5340
return null;

0 commit comments

Comments
 (0)