fix: avoid emitting focus events twice

fixes #6749
This commit is contained in:
Satyajit Sahoo
2020-02-21 18:56:06 +01:00
parent 240ce01822
commit f16700812f
2 changed files with 41 additions and 15 deletions

View File

@@ -188,10 +188,12 @@ it('fires focus and blur events in nested navigator', () => {
expect(thirdFocusCallback).toBeCalledTimes(0);
expect(secondFocusCallback).toBeCalledTimes(1);
expect(fourthBlurCallback).toBeCalledTimes(0);
act(() => parent.current.navigate('nested'));
expect(firstBlurCallback).toBeCalledTimes(1);
expect(secondBlurCallback).toBeCalledTimes(1);
expect(thirdFocusCallback).toBeCalledTimes(0);
expect(fourthFocusCallback).toBeCalledTimes(1);
@@ -199,6 +201,35 @@ it('fires focus and blur events in nested navigator', () => {
expect(fourthBlurCallback).toBeCalledTimes(1);
expect(thirdFocusCallback).toBeCalledTimes(1);
act(() => parent.current.navigate('first'));
expect(firstFocusCallback).toBeCalledTimes(2);
expect(thirdBlurCallback).toBeCalledTimes(1);
act(() => parent.current.navigate('nested', { screen: 'fourth' }));
expect(fourthFocusCallback).toBeCalledTimes(2);
expect(thirdBlurCallback).toBeCalledTimes(1);
expect(firstBlurCallback).toBeCalledTimes(2);
act(() => parent.current.navigate('nested', { screen: 'third' }));
expect(thirdFocusCallback).toBeCalledTimes(2);
expect(fourthBlurCallback).toBeCalledTimes(2);
// Make sure nothing else has changed
expect(firstFocusCallback).toBeCalledTimes(2);
expect(firstBlurCallback).toBeCalledTimes(2);
expect(secondFocusCallback).toBeCalledTimes(1);
expect(secondBlurCallback).toBeCalledTimes(1);
expect(thirdFocusCallback).toBeCalledTimes(2);
expect(thirdBlurCallback).toBeCalledTimes(1);
expect(fourthFocusCallback).toBeCalledTimes(2);
expect(fourthBlurCallback).toBeCalledTimes(2);
});
it('fires blur event when a route is removed with a delay', async () => {

View File

@@ -21,17 +21,19 @@ export default function useFocusEvents({ state, emitter }: Options) {
// Coz the child screen can't be focused if the parent screen is out of focus
React.useEffect(
() =>
navigation?.addListener('focus', () =>
emitter.emit({ type: 'focus', target: currentFocusedKey })
),
navigation?.addListener('focus', () => {
lastFocusedKeyRef.current = currentFocusedKey;
emitter.emit({ type: 'focus', target: currentFocusedKey });
}),
[currentFocusedKey, emitter, navigation]
);
React.useEffect(
() =>
navigation?.addListener('blur', () =>
emitter.emit({ type: 'blur', target: currentFocusedKey })
),
navigation?.addListener('blur', () => {
lastFocusedKeyRef.current = undefined;
emitter.emit({ type: 'blur', target: currentFocusedKey });
}),
[currentFocusedKey, emitter, navigation]
);
@@ -60,14 +62,7 @@ export default function useFocusEvents({ state, emitter }: Options) {
return;
}
emitter.emit({
type: 'focus',
target: currentFocusedKey,
});
emitter.emit({
type: 'blur',
target: lastFocusedKey,
});
emitter.emit({ type: 'focus', target: currentFocusedKey });
emitter.emit({ type: 'blur', target: lastFocusedKey });
}, [currentFocusedKey, emitter, navigation]);
}