1 | import type { NavigationState } from '@react-navigation/routers';
|
2 | import * as React from 'react';
|
3 |
|
4 | import isArrayEqual from './isArrayEqual';
|
5 | import NavigationBuilderContext, {
|
6 | GetStateListener,
|
7 | } from './NavigationBuilderContext';
|
8 | import NavigationRouteContext from './NavigationRouteContext';
|
9 |
|
10 | type Options = {
|
11 | getState: () => NavigationState;
|
12 | getStateListeners: Record<string, GetStateListener | undefined>;
|
13 | };
|
14 |
|
15 | export default function useOnGetState({
|
16 | getState,
|
17 | getStateListeners,
|
18 | }: Options) {
|
19 | const { addKeyedListener } = React.useContext(NavigationBuilderContext);
|
20 | const route = React.useContext(NavigationRouteContext);
|
21 | const key = route ? route.key : 'root';
|
22 |
|
23 | const getRehydratedState = React.useCallback(() => {
|
24 | const state = getState();
|
25 |
|
26 |
|
27 | const routes = state.routes.map((route) => {
|
28 | const childState = getStateListeners[route.key]?.();
|
29 |
|
30 | if (route.state === childState) {
|
31 | return route;
|
32 | }
|
33 |
|
34 | return { ...route, state: childState };
|
35 | });
|
36 |
|
37 | if (isArrayEqual(state.routes, routes)) {
|
38 | return state;
|
39 | }
|
40 |
|
41 | return { ...state, routes };
|
42 | }, [getState, getStateListeners]);
|
43 |
|
44 | React.useEffect(() => {
|
45 | return addKeyedListener?.('getState', key, getRehydratedState);
|
46 | }, [addKeyedListener, getRehydratedState, key]);
|
47 | }
|