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

Commit a03b8d7

Browse files
committed
Add refocus event and fix child navigation caching
1 parent 612713f commit a03b8d7

4 files changed

Lines changed: 76 additions & 40 deletions

File tree

src/getChildEventSubscriber.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export default function getChildEventSubscriber(addListener, key) {
1010
const didFocusSubscribers = new Set();
1111
const willBlurSubscribers = new Set();
1212
const didBlurSubscribers = new Set();
13+
const refocusSubscribers = new Set();
1314

1415
const removeAll = () => {
1516
[
@@ -18,6 +19,7 @@ export default function getChildEventSubscriber(addListener, key) {
1819
didFocusSubscribers,
1920
willBlurSubscribers,
2021
didBlurSubscribers,
22+
refocusSubscribers,
2123
].forEach(set => set.clear());
2224

2325
upstreamSubscribers.forEach(subs => subs && subs.remove());
@@ -35,6 +37,8 @@ export default function getChildEventSubscriber(addListener, key) {
3537
return willBlurSubscribers;
3638
case 'didBlur':
3739
return didBlurSubscribers;
40+
case 'refocus':
41+
return refocusSubscribers;
3842
default:
3943
return null;
4044
}
@@ -60,11 +64,17 @@ export default function getChildEventSubscriber(addListener, key) {
6064
'didFocus',
6165
'willBlur',
6266
'didBlur',
67+
'refocus',
6368
'action',
6469
];
6570

6671
const upstreamSubscribers = upstreamEvents.map(eventName =>
6772
addListener(eventName, payload => {
73+
if (eventName === 'refocus') {
74+
emit(eventName, payload);
75+
return;
76+
}
77+
6878
const { state, lastState, action } = payload;
6979
const lastRoutes = lastState && lastState.routes;
7080
const routes = state && state.routes;
@@ -157,5 +167,12 @@ export default function getChildEventSubscriber(addListener, key) {
157167
};
158168
return { remove };
159169
},
170+
emit(eventName, payload) {
171+
if (eventName !== 'refocus') {
172+
console.error(`navigation.emit only supports the 'refocus' event currently.`);
173+
return;
174+
}
175+
emit(eventName, payload);
176+
}
160177
};
161178
}

src/getChildNavigation.js

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import getChildEventSubscriber from './getChildEventSubscriber';
22
import getChildRouter from './getChildRouter';
33
import getNavigationActionCreators from './routers/getNavigationActionCreators';
4+
import getChildrenNavigationCache from './getChildrenNavigationCache';
45

56
const createParamGetter = route => (paramName, defaultValue) => {
67
const params = route.params;
@@ -13,9 +14,7 @@ const createParamGetter = route => (paramName, defaultValue) => {
1314
};
1415

1516
function getChildNavigation(navigation, childKey, getCurrentParentNavigation) {
16-
const children =
17-
navigation._childrenNavigation || (navigation._childrenNavigation = {});
18-
17+
const children = getChildrenNavigationCache(navigation);
1918
const childRoute = navigation.state.routes.find(r => r.key === childKey);
2019

2120
if (!childRoute) {
@@ -66,47 +65,48 @@ function getChildNavigation(navigation, childKey, getCurrentParentNavigation) {
6665
getParam: createParamGetter(childRoute),
6766
};
6867
return children[childKey];
69-
}
70-
71-
const childSubscriber = getChildEventSubscriber(
72-
navigation.addListener,
73-
childKey
74-
);
75-
76-
children[childKey] = {
77-
...actionHelpers,
68+
} else {
69+
const childSubscriber = getChildEventSubscriber(
70+
navigation.addListener,
71+
childKey
72+
);
7873

79-
state: childRoute,
80-
router: childRouter,
81-
actions: actionCreators,
82-
getParam: createParamGetter(childRoute),
74+
children[childKey] = {
75+
...actionHelpers,
8376

84-
getChildNavigation: grandChildKey =>
85-
getChildNavigation(children[childKey], grandChildKey, () => {
86-
const nav = getCurrentParentNavigation();
87-
return nav && nav.getChildNavigation(childKey);
88-
}),
77+
state: childRoute,
78+
router: childRouter,
79+
actions: actionCreators,
80+
getParam: createParamGetter(childRoute),
8981

90-
isFocused: () => {
91-
const currentNavigation = getCurrentParentNavigation();
92-
if (!currentNavigation) {
82+
getChildNavigation: grandChildKey =>
83+
getChildNavigation(children[childKey], grandChildKey, () => {
84+
const nav = getCurrentParentNavigation();
85+
return nav && nav.getChildNavigation(childKey);
86+
}),
87+
88+
isFocused: () => {
89+
const currentNavigation = getCurrentParentNavigation();
90+
if (!currentNavigation) {
91+
return false;
92+
}
93+
const { routes, index } = currentNavigation.state;
94+
if (!currentNavigation.isFocused()) {
95+
return false;
96+
}
97+
if (routes[index].key === childKey) {
98+
return true;
99+
}
93100
return false;
94-
}
95-
const { routes, index } = currentNavigation.state;
96-
if (!currentNavigation.isFocused()) {
97-
return false;
98-
}
99-
if (routes[index].key === childKey) {
100-
return true;
101-
}
102-
return false;
103-
},
104-
dispatch: navigation.dispatch,
105-
getScreenProps: navigation.getScreenProps,
106-
dangerouslyGetParent: getCurrentParentNavigation,
107-
addListener: childSubscriber.addListener,
108-
};
109-
return children[childKey];
101+
},
102+
dispatch: navigation.dispatch,
103+
getScreenProps: navigation.getScreenProps,
104+
dangerouslyGetParent: getCurrentParentNavigation,
105+
addListener: childSubscriber.addListener,
106+
emit: childSubscriber.emit,
107+
};
108+
return children[childKey];
109+
}
110110
}
111111

112112
export default getChildNavigation;

src/getChildrenNavigationCache.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export default function getChildrenNavigationCache(navigation) {
2+
if (!navigation) {
3+
return {};
4+
}
5+
6+
let childrenNavigationCache = navigation._childrenNavigation
7+
? navigation._childrenNavigation
8+
: {};
9+
let childKeys = navigation.state.routes.map(route => route.key);
10+
Object.keys(childrenNavigationCache).forEach(cacheKey => {
11+
if (!childKeys.includes(cacheKey)) {
12+
delete childrenNavigationCache[cacheKey];
13+
}
14+
});
15+
16+
return childrenNavigationCache;
17+
}

src/getNavigation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import getNavigationActionCreators from './routers/getNavigationActionCreators';
22
import getChildNavigation from './getChildNavigation';
3+
import getChildrenNavigationCache from './getChildrenNavigationCache';
34

45
export default function getNavigation(
56
router,
@@ -38,6 +39,7 @@ export default function getNavigation(
3839
};
3940
},
4041
dangerouslyGetParent: () => null,
42+
_childrenNavigation: getChildrenNavigationCache(getCurrentNavigation())
4143
};
4244

4345
const actionCreators = {

0 commit comments

Comments
 (0)