UNPKG

1.33 kBTypeScriptView Raw
1import type { NavigationState, ParamListBase } from '@react-navigation/routers';
2import * as React from 'react';
3
4import type { NavigationProp } from './types';
5import useNavigation from './useNavigation';
6
7type Selector<ParamList extends ParamListBase, T> = (
8 state: NavigationState<ParamList>
9) => T;
10
11/**
12 * Hook to get a value from the current navigation state using a selector.
13 *
14 * @param selector Selector function to get a value from the state.
15 */
16export default function useNavigationState<ParamList extends ParamListBase, T>(
17 selector: Selector<ParamList, T>
18): T {
19 const navigation = useNavigation<NavigationProp<ParamList>>();
20
21 // We don't care about the state value, we run the selector again at the end
22 // The state is only to make sure that there's a re-render when we have a new value
23 const [, setResult] = React.useState(() => selector(navigation.getState()));
24
25 // We store the selector in a ref to avoid re-subscribing listeners every render
26 const selectorRef = React.useRef(selector);
27
28 React.useEffect(() => {
29 selectorRef.current = selector;
30 });
31
32 React.useEffect(() => {
33 const unsubscribe = navigation.addListener('state', (e) => {
34 setResult(selectorRef.current(e.data.state));
35 });
36
37 return unsubscribe;
38 }, [navigation]);
39
40 return selector(navigation.getState());
41}