This repository has been archived by the owner on Feb 8, 2020. It is now read-only.
generated from satya164/typescript-template
-
Notifications
You must be signed in to change notification settings - Fork 41
/
useFocusEffect.tsx
50 lines (42 loc) · 1.54 KB
/
useFocusEffect.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import * as React from 'react';
import useNavigation from './useNavigation';
type EffectCallback = (() => void) | (() => () => void);
/**
* Hook to run an effect in a focused screen, similar to `React.useEffect`.
* This can be used to perform side-effects such as fetching data or subscribing to events.
* The passed callback should be wrapped in `React.useCallback` to avoid running the effect too often.
*
* @param callback Memoized callback containing the effect, should optionally return a cleanup function.
*/
export default function useFocusEffect(callback: EffectCallback) {
const navigation = useNavigation();
React.useEffect(() => {
let isFocused = false;
let cleanup: (() => void) | void;
// We need to run the effect on intial render/dep changes if the screen is focused
if (navigation.isFocused()) {
cleanup = callback();
isFocused = true;
}
const unsubscribeFocus = navigation.addListener('focus', () => {
// If callback was already called for focus, avoid calling it again
// The focus event may also fire on intial render, so we guard against runing the effect twice
if (isFocused) {
return;
}
cleanup && cleanup();
cleanup = callback();
isFocused = true;
});
const unsubscribeBlur = navigation.addListener('blur', () => {
cleanup && cleanup();
cleanup = undefined;
isFocused = false;
});
return () => {
cleanup && cleanup();
unsubscribeFocus();
unsubscribeBlur();
};
}, [callback, navigation]);
}