1 | import * as React from 'react';
|
2 | import NavigationBuilderContext from './NavigationBuilderContext';
|
3 | import NavigationContext from './NavigationContext';
|
4 | import NavigationRouteContext from './NavigationRouteContext';
|
5 | import SceneView from './SceneView';
|
6 | import useNavigationCache from './useNavigationCache';
|
7 | import useRouteCache from './useRouteCache';
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | export default function useDescriptors(_ref) {
|
18 | let {
|
19 | state,
|
20 | screens,
|
21 | navigation,
|
22 | screenOptions,
|
23 | defaultScreenOptions,
|
24 | onAction,
|
25 | getState,
|
26 | setState,
|
27 | addListener,
|
28 | addKeyedListener,
|
29 | onRouteFocus,
|
30 | router,
|
31 | emitter
|
32 | } = _ref;
|
33 | const [options, setOptions] = React.useState({});
|
34 | const {
|
35 | onDispatchAction,
|
36 | onOptionsChange,
|
37 | stackRef
|
38 | } = React.useContext(NavigationBuilderContext);
|
39 | const context = React.useMemo(() => ({
|
40 | navigation,
|
41 | onAction,
|
42 | addListener,
|
43 | addKeyedListener,
|
44 | onRouteFocus,
|
45 | onDispatchAction,
|
46 | onOptionsChange,
|
47 | stackRef
|
48 | }), [navigation, onAction, addListener, addKeyedListener, onRouteFocus, onDispatchAction, onOptionsChange, stackRef]);
|
49 | const navigations = useNavigationCache({
|
50 | state,
|
51 | getState,
|
52 | navigation,
|
53 | setOptions,
|
54 | router,
|
55 | emitter
|
56 | });
|
57 | const routes = useRouteCache(state.routes);
|
58 | return routes.reduce((acc, route, i) => {
|
59 | const config = screens[route.name];
|
60 | const screen = config.props;
|
61 | const navigation = navigations[route.key];
|
62 | const optionsList = [
|
63 | screenOptions,
|
64 | ...(config.options ? config.options.filter(Boolean) : []),
|
65 | screen.options,
|
66 | options[route.key]];
|
67 | const customOptions = optionsList.reduce((acc, curr) => Object.assign(acc, typeof curr !== 'function' ? curr : curr({
|
68 | route,
|
69 | navigation
|
70 | })), {});
|
71 | const mergedOptions = { ...(typeof defaultScreenOptions === 'function' ?
|
72 | defaultScreenOptions({
|
73 | route,
|
74 | navigation,
|
75 | options: customOptions
|
76 | }) : defaultScreenOptions),
|
77 | ...customOptions
|
78 | };
|
79 |
|
80 | const clearOptions = () => setOptions(o => {
|
81 | if (route.key in o) {
|
82 |
|
83 | const {
|
84 | [route.key]: _,
|
85 | ...rest
|
86 | } = o;
|
87 | return rest;
|
88 | }
|
89 |
|
90 | return o;
|
91 | });
|
92 |
|
93 | acc[route.key] = {
|
94 | route,
|
95 |
|
96 | navigation,
|
97 |
|
98 | render() {
|
99 | return React.createElement(NavigationBuilderContext.Provider, {
|
100 | key: route.key,
|
101 | value: context
|
102 | }, React.createElement(NavigationContext.Provider, {
|
103 | value: navigation
|
104 | }, React.createElement(NavigationRouteContext.Provider, {
|
105 | value: route
|
106 | }, React.createElement(SceneView, {
|
107 | navigation: navigation,
|
108 | route: route,
|
109 | screen: screen,
|
110 | routeState: state.routes[i].state,
|
111 | getState: getState,
|
112 | setState: setState,
|
113 | options: mergedOptions,
|
114 | clearOptions: clearOptions
|
115 | }))));
|
116 | },
|
117 |
|
118 | options: mergedOptions
|
119 | };
|
120 | return acc;
|
121 | }, {});
|
122 | }
|
123 |
|
\ | No newline at end of file |