@applicaster/zapp-react-native-utils 14.0.0-alpha.9119252693 → 14.0.0-alpha.9203091422

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/actionsExecutor/ActionExecutorContext.tsx +60 -83
  2. package/actionsExecutor/ScreenActions.ts +163 -0
  3. package/actionsExecutor/StorageActions.ts +110 -0
  4. package/actionsExecutor/feedDecorator.ts +171 -0
  5. package/actionsExecutor/screenResolver.ts +11 -0
  6. package/analyticsUtils/AnalyticsEvents/helper.ts +1 -1
  7. package/analyticsUtils/AnalyticsEvents/sendHeaderClickEvent.ts +1 -1
  8. package/analyticsUtils/AnalyticsEvents/sendMenuClickEvent.ts +2 -1
  9. package/analyticsUtils/index.tsx +3 -4
  10. package/analyticsUtils/manager.ts +1 -1
  11. package/appUtils/HooksManager/Hook.ts +4 -4
  12. package/appUtils/HooksManager/index.ts +11 -1
  13. package/appUtils/accessibilityManager/index.ts +3 -3
  14. package/appUtils/contextKeysManager/contextResolver.ts +14 -1
  15. package/arrayUtils/index.ts +1 -1
  16. package/componentsUtils/__tests__/isTabsScreen.test.ts +38 -0
  17. package/componentsUtils/index.ts +4 -1
  18. package/configurationUtils/__tests__/manifestKeyParser.test.ts +547 -0
  19. package/configurationUtils/manifestKeyParser.ts +57 -32
  20. package/index.d.ts +0 -9
  21. package/package.json +2 -2
  22. package/reactHooks/autoscrolling/__tests__/useTrackedView.test.tsx +12 -13
  23. package/reactHooks/cell-click/index.ts +8 -1
  24. package/reactHooks/feed/__tests__/useBatchLoading.test.tsx +39 -88
  25. package/reactHooks/feed/__tests__/useFeedLoader.test.tsx +20 -0
  26. package/reactHooks/feed/useFeedLoader.tsx +12 -5
  27. package/reactHooks/layout/isTablet/index.ts +7 -3
  28. package/reactHooks/navigation/index.ts +7 -5
  29. package/reactHooks/navigation/useRoute.ts +7 -2
  30. package/reactHooks/navigation/useScreenStateStore.ts +8 -0
  31. package/storage/ScreenSingleValueProvider.ts +201 -0
  32. package/storage/ScreenStateMultiSelectProvider.ts +290 -0
  33. package/storage/StorageMultiSelectProvider.ts +192 -0
  34. package/storage/StorageSingleSelectProvider.ts +108 -0
  35. package/testUtils/index.tsx +7 -8
@@ -1,25 +1,27 @@
1
1
  import React from "react";
2
2
 
3
- import { act, renderHook } from "@testing-library/react-hooks";
3
+ import { renderHook } from "@testing-library/react-hooks";
4
+ import { act, waitFor } from "@testing-library/react-native";
4
5
  import { Provider } from "react-redux";
5
6
  import configureStore from "redux-mock-store";
7
+ import { useTrackedView } from "../useTrackedView";
6
8
 
7
9
  const mockUpdateComponentsPositions = jest.fn();
8
10
 
9
11
  jest.mock(
10
12
  "@applicaster/zapp-react-native-ui-components/Contexts/ScreenTrackedViewPositionsContext",
11
13
  () => ({
12
- useScreenTrackedViewPositionsContext: jest.fn().mockReturnValue({
14
+ useScreenTrackedViewPositionsContext: jest.fn(() => ({
13
15
  updateComponentsPositions: mockUpdateComponentsPositions,
14
16
  value: {
15
17
  "123": { componentId: "123", centerX: 0.4, centerY: 0.5 },
16
18
  "124": { componentId: "124", centerX: 0.2, centerY: 0.3 },
17
19
  },
18
- }),
20
+ })),
19
21
  })
20
22
  );
21
23
 
22
- jest.useFakeTimers({ legacyFakeTimers: true });
24
+ jest.useFakeTimers();
23
25
 
24
26
  jest.mock("@applicaster/zapp-react-native-utils/reactHooks/navigation");
25
27
 
@@ -32,10 +34,8 @@ const Wrapper = ({ children }: { children: React.ReactChild }) => (
32
34
  <Provider store={store}>{children}</Provider>
33
35
  );
34
36
 
35
- const { useTrackedView } = require("../useTrackedView");
36
-
37
37
  describe("useTrackCurrentAutoScrollingElement", () => {
38
- it("should update position for selected component - onViewportEnter", () => {
38
+ it("should update position for selected component - onViewportEnter", async () => {
39
39
  const { result } = renderHook(() => useTrackedView("123"), {
40
40
  wrapper: Wrapper,
41
41
  });
@@ -46,14 +46,13 @@ describe("useTrackCurrentAutoScrollingElement", () => {
46
46
  rect: { left: 1, right: 1, top: 1, bottom: 1 },
47
47
  };
48
48
 
49
- act(async () => {
50
- await result.current.onPositionUpdated(mockRect);
49
+ act(() => {
50
+ result.current.onPositionUpdated(mockRect);
51
51
  });
52
52
 
53
- // Fast-forward until all timers have been executed
54
- jest.runAllTimers();
55
-
56
- expect(result.current.inViewPort).toBe(true);
53
+ await waitFor(() => {
54
+ expect(result.current.inViewPort).toBe(true);
55
+ });
57
56
 
58
57
  expect(mockUpdateComponentsPositions).toHaveBeenCalledWith(
59
58
  "123",
@@ -16,7 +16,8 @@ import { ActionExecutorContext } from "@applicaster/zapp-react-native-utils/acti
16
16
  import { isFunction, noop } from "../../functionUtils";
17
17
  import { useSendAnalyticsOnPress } from "../analytics";
18
18
  import { logOnPress, warnEmptyContentType } from "./helpers";
19
- import { useCurrentScreenData } from "../screen";
19
+ import { useCurrentScreenData, useScreenContext } from "../screen";
20
+ import { useScreenStateStore } from "../navigation/useScreenStateStore";
20
21
 
21
22
  /**
22
23
  * If onCellTap is defined execute the function and
@@ -42,10 +43,12 @@ export const useCellClick = ({
42
43
  }: Props): onPressReturnFn => {
43
44
  const { push, currentRoute } = useNavigation();
44
45
  const { pathname } = useRoute();
46
+ const screenStateStore = useScreenStateStore();
45
47
 
46
48
  const onCellTap: Option<Function> = React.useContext(CellTapContext);
47
49
  const actionExecutor = React.useContext(ActionExecutorContext);
48
50
  const screenData = useCurrentScreenData();
51
+ const screenState = useScreenContext()?.options;
49
52
 
50
53
  const cellSelectable = toBooleanWithDefaultTrue(
51
54
  component?.rules?.component_cells_selectable
@@ -83,6 +86,9 @@ export const useCellClick = ({
83
86
  await actionExecutor?.handleEntryActions(selectedItem, {
84
87
  component,
85
88
  screenData,
89
+ screenState,
90
+ screenRoute: pathname,
91
+ screenStateStore,
86
92
  });
87
93
  }
88
94
 
@@ -117,6 +123,7 @@ export const useCellClick = ({
117
123
  push,
118
124
  sendAnalyticsOnPress,
119
125
  screenData,
126
+ screenState,
120
127
  ]
121
128
  );
122
129
 
@@ -1,8 +1,7 @@
1
1
  import { renderHook } from "@testing-library/react-hooks";
2
- import * as reduxMockStore from "redux-mock-store";
3
- import thunk from "redux-thunk";
4
- import React from "react";
5
- import * as ReactRedux from "react-redux";
2
+ import { allFeedsIsReady, useBatchLoading } from "../useBatchLoading";
3
+ import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
4
+ import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
6
5
 
7
6
  jest.mock("../../navigation");
8
7
 
@@ -13,17 +12,18 @@ jest.mock(
13
12
  })
14
13
  );
15
14
 
16
- const useBatchLoading = require("../useBatchLoading").useBatchLoading;
17
- const allFeedsIsReady = require("../useBatchLoading").allFeedsIsReady;
18
-
19
- const mockStore = reduxMockStore.default([thunk]);
20
-
21
- const wrapper: React.FC<any> = ({ children, store }) => (
22
- <ReactRedux.Provider store={store}>{children}</ReactRedux.Provider>
23
- );
15
+ const wrapper = WrappedWithProviders;
24
16
 
25
17
  describe("useBatchLoading", () => {
26
- const useDispatchSpy = jest.spyOn(ReactRedux, "useDispatch");
18
+ const data = [
19
+ { data: { source: "url1" }, component_type: "any" },
20
+ { data: { source: "url2" }, component_type: "any" },
21
+ { data: { source: "url3" }, component_type: "any" },
22
+ { data: { source: "url4" }, component_type: "any" },
23
+ { data: { source: "url5" }, component_type: "any" },
24
+ { data: { source: "url6" }, component_type: "any" },
25
+ // ... more items
26
+ ];
27
27
 
28
28
  beforeAll(() => {
29
29
  jest.useFakeTimers();
@@ -34,7 +34,7 @@ describe("useBatchLoading", () => {
34
34
  });
35
35
 
36
36
  it("loadPipesData start loading not started requests", () => {
37
- const store = mockStore({
37
+ const store = {
38
38
  zappPipes: {
39
39
  url1: {
40
40
  loading: true,
@@ -53,29 +53,17 @@ describe("useBatchLoading", () => {
53
53
  },
54
54
  },
55
55
  test: "true",
56
- });
57
-
58
- useDispatchSpy.mockReturnValue(store.dispatch);
56
+ };
59
57
 
60
58
  const initialBatchSize = 3;
61
59
  const riverId = "123";
62
60
 
63
- const data = [
64
- { data: { source: "url1" } },
65
- { data: { source: "url2" } },
66
- { data: { source: "url3" } },
67
- { data: { source: "url4" } },
68
- { data: { source: "url5" } },
69
- { data: { source: "url6" } },
70
- // ... more items
71
- ];
72
-
73
61
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
74
62
  wrapper,
75
63
  initialProps: { store },
76
64
  });
77
65
 
78
- const actions = store.getActions();
66
+ const actions = (appStore.getStore() as any).getActions();
79
67
 
80
68
  expect(actions).toHaveLength(2);
81
69
 
@@ -91,7 +79,7 @@ describe("useBatchLoading", () => {
91
79
  });
92
80
 
93
81
  it("loadPipesData start loading new feed when 1 feed is done loading and 1 is in loading state", () => {
94
- const store = mockStore({
82
+ const store = {
95
83
  zappPipes: {
96
84
  url1: {
97
85
  loading: false,
@@ -110,31 +98,17 @@ describe("useBatchLoading", () => {
110
98
  },
111
99
  },
112
100
  test: "true",
113
- });
114
-
115
- useDispatchSpy.mockReturnValue(store.dispatch);
101
+ };
116
102
 
117
103
  const initialBatchSize = 3;
118
104
  const riverId = "123";
119
105
 
120
- const data = [
121
- { data: { source: "url1" } },
122
- { data: { source: "url2" } },
123
- { data: { source: "url3" } },
124
- { data: { source: "url4" } },
125
- { data: { source: "url5" } },
126
- { data: { source: "url6" } },
127
- // ... more items
128
- ];
129
-
130
- expect(useDispatchSpy).toBeCalledTimes(0);
131
-
132
106
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
133
107
  wrapper,
134
108
  initialProps: { store },
135
109
  });
136
110
 
137
- const actions = store.getActions();
111
+ const actions = (appStore.getStore() as any).getActions();
138
112
 
139
113
  expect(actions).toHaveLength(1);
140
114
 
@@ -145,38 +119,26 @@ describe("useBatchLoading", () => {
145
119
  });
146
120
 
147
121
  it("loadPipesData has been called when no data cached", () => {
148
- const store = mockStore({
122
+ const store = {
149
123
  zappPipes: {},
150
124
  test: "true",
151
- });
152
-
153
- useDispatchSpy.mockReturnValue(store.dispatch);
125
+ };
154
126
 
155
127
  const initialBatchSize = 3;
156
128
  const riverId = "123";
157
129
 
158
- const data = [
159
- { data: { source: "url1" } },
160
- { data: { source: "url2" } },
161
- { data: { source: "url3" } },
162
- { data: { source: "url4" } },
163
- { data: { source: "url5" } },
164
- { data: { source: "url6" } },
165
- // ... more items
166
- ];
167
-
168
130
  renderHook(() => useBatchLoading(data, { initialBatchSize, riverId }), {
169
131
  wrapper,
170
132
  initialProps: { store },
171
133
  });
172
134
 
173
- const actions = store.getActions();
135
+ const actions = (appStore.getStore() as any).getActions();
174
136
 
175
137
  expect(actions).toHaveLength(3);
176
138
  });
177
139
 
178
140
  it("initial batch ready when all initial items loaded", () => {
179
- const store = mockStore({
141
+ const store = {
180
142
  zappPipes: {
181
143
  url1: {
182
144
  loading: false,
@@ -194,19 +156,11 @@ describe("useBatchLoading", () => {
194
156
  data: {},
195
157
  },
196
158
  },
197
- });
198
-
199
- useDispatchSpy.mockReturnValue(store.dispatch);
159
+ };
200
160
 
201
161
  const initialBatchSize = 3;
202
162
  const riverId = "123";
203
163
 
204
- const data: Partial<ZappUIComponent>[] = [
205
- { data: { source: "url1" } },
206
- { data: { source: "url2" } },
207
- { data: { source: "url3" } },
208
- ];
209
-
210
164
  const { result } = renderHook(
211
165
  () => useBatchLoading(data, { initialBatchSize, riverId }),
212
166
  { wrapper, initialProps: { store } }
@@ -216,12 +170,10 @@ describe("useBatchLoading", () => {
216
170
  });
217
171
 
218
172
  it("gallery-qb: loadPipesData should be called only once for first component in the gallery", () => {
219
- const store = mockStore({
173
+ const store = {
220
174
  zappPipes: {},
221
175
  test: "true",
222
- });
223
-
224
- useDispatchSpy.mockReturnValue(store.dispatch);
176
+ };
225
177
 
226
178
  const initialBatchSize = 3;
227
179
  const riverId = "123";
@@ -231,11 +183,11 @@ describe("useBatchLoading", () => {
231
183
  component_type: "gallery-qb",
232
184
  ui_components: [{ data: { source: "url1" } }],
233
185
  },
234
- { data: { source: "url2" } },
235
- { data: { source: "url3" } },
236
- { data: { source: "url4" } },
237
- { data: { source: "url5" } },
238
- { data: { source: "url6" } },
186
+ { data: { source: "url2" }, component_type: "any" },
187
+ { data: { source: "url3" }, component_type: "any" },
188
+ { data: { source: "url4" }, component_type: "any" },
189
+ { data: { source: "url5" }, component_type: "any" },
190
+ { data: { source: "url6" }, component_type: "any" },
239
191
  // ... more items
240
192
  ];
241
193
 
@@ -244,13 +196,13 @@ describe("useBatchLoading", () => {
244
196
  initialProps: { store },
245
197
  });
246
198
 
247
- const actions = store.getActions();
199
+ const actions = (appStore.getStore() as any).getActions();
248
200
 
249
201
  expect(actions).toHaveLength(1);
250
202
  });
251
203
 
252
204
  it("gallery-qb: initial batch ready when all initial items loaded", () => {
253
- const store = mockStore({
205
+ const store = {
254
206
  zappPipes: {
255
207
  url1: {
256
208
  loading: false,
@@ -258,20 +210,19 @@ describe("useBatchLoading", () => {
258
210
  data: {},
259
211
  },
260
212
  },
261
- });
262
-
263
- useDispatchSpy.mockReturnValue(store.dispatch);
213
+ };
264
214
 
265
215
  const initialBatchSize = 3;
266
216
  const riverId = "123";
267
217
 
268
- const data: Partial<ZappUIComponent>[] = [
218
+ const data = [
269
219
  {
270
220
  component_type: "gallery-qb",
271
- ui_components: [{ data: { source: "url1" } }],
221
+ data: {},
222
+ ui_components: [{ data: { source: "url1" } }] as any,
272
223
  },
273
- { data: { source: "url2" } },
274
- { data: { source: "url3" } },
224
+ { data: { source: "url2" }, component_type: "any" },
225
+ { data: { source: "url3" }, component_type: "any" },
275
226
  ];
276
227
 
277
228
  const { result } = renderHook(
@@ -138,6 +138,11 @@ describe("useFeedLoader", () => {
138
138
  expect(loadPipesDataSpy).toBeCalledWith(feedUrl, {
139
139
  clearCache: true,
140
140
  riverId: undefined,
141
+ resolvers: {
142
+ screen: {
143
+ screenStateStore: undefined,
144
+ },
145
+ },
141
146
  });
142
147
 
143
148
  const store2 = mockStore({
@@ -179,6 +184,11 @@ describe("useFeedLoader", () => {
179
184
  expect(loadPipesDataSpy).toBeCalledWith(feedUrl, {
180
185
  clearCache: true,
181
186
  riverId: undefined,
187
+ resolvers: {
188
+ screen: {
189
+ screenStateStore: undefined,
190
+ },
191
+ },
182
192
  });
183
193
 
184
194
  const store2 = mockStore({
@@ -228,6 +238,11 @@ describe("useFeedLoader", () => {
228
238
  expect(loadPipesDataSpy).toBeCalledWith(feedUrl, {
229
239
  clearCache: true,
230
240
  silentRefresh: true,
241
+ resolvers: {
242
+ screen: {
243
+ screenStateStore: undefined,
244
+ },
245
+ },
231
246
  });
232
247
 
233
248
  loadPipesDataSpy.mockRestore();
@@ -267,6 +282,11 @@ describe("useFeedLoader", () => {
267
282
  expect(loadPipesDataSpy).toBeCalledWith(nextUrl, {
268
283
  parentFeed: feedUrlWithNext,
269
284
  silentRefresh: true,
285
+ resolvers: {
286
+ screen: {
287
+ screenStateStore: undefined,
288
+ },
289
+ },
270
290
  });
271
291
 
272
292
  loadPipesDataSpy.mockRestore();
@@ -8,6 +8,7 @@ import { reactHooksLogger } from "../logger";
8
8
  import { shouldDispatchData, useIsInitialRender } from "../utils";
9
9
  import { useInflatedUrl } from "./useInflatedUrl";
10
10
  import { useRoute } from "../navigation";
11
+ import { useScreenResolvers } from "@applicaster/zapp-react-native-utils/actionsExecutor/screenResolver";
11
12
 
12
13
  const logger = reactHooksLogger.addSubsystem("useFeedLoader");
13
14
 
@@ -51,6 +52,7 @@ export const useFeedLoader = ({
51
52
  const isInitialRender = useIsInitialRender();
52
53
  const dispatch = useDispatch();
53
54
  const { screenData } = useRoute();
55
+ const resolvers = useScreenResolvers();
54
56
 
55
57
  const callableFeedUrl = useInflatedUrl({ feedUrl, mapping });
56
58
 
@@ -69,11 +71,12 @@ export const useFeedLoader = ({
69
71
  silentRefresh,
70
72
  callback,
71
73
  riverId,
74
+ resolvers,
72
75
  })
73
76
  );
74
77
  }
75
78
  },
76
- [callableFeedUrl]
79
+ [callableFeedUrl, resolvers]
77
80
  );
78
81
 
79
82
  const loadNext: FeedLoaderResponse["loadNext"] = React.useCallback(() => {
@@ -86,11 +89,12 @@ export const useFeedLoader = ({
86
89
  silentRefresh: true,
87
90
  parentFeed: callableFeedUrl,
88
91
  riverId,
92
+ resolvers,
89
93
  })
90
94
  );
91
95
  }
92
96
  }
93
- }, [callableFeedUrl, currentFeed?.data?.next]);
97
+ }, [callableFeedUrl, currentFeed?.data?.next, resolvers]);
94
98
 
95
99
  useEffect(() => {
96
100
  if (
@@ -102,6 +106,7 @@ export const useFeedLoader = ({
102
106
  ...pipesOptions,
103
107
  clearCache: true,
104
108
  riverId,
109
+ resolvers,
105
110
  })
106
111
  );
107
112
  } else if (!callableFeedUrl) {
@@ -126,14 +131,16 @@ export const useFeedLoader = ({
126
131
  jsOnly: true,
127
132
  });
128
133
  }
129
- }, []);
134
+ }, [resolvers]);
130
135
 
131
136
  // Reload feed when feedUrl changes, unless skipLoading is true
132
137
  useEffect(() => {
133
138
  if (!isInitialRender && callableFeedUrl && !pipesOptions.skipLoading) {
134
- dispatch(loadPipesData(callableFeedUrl, { ...pipesOptions, riverId }));
139
+ dispatch(
140
+ loadPipesData(callableFeedUrl, { ...pipesOptions, riverId, resolvers })
141
+ );
135
142
  }
136
- }, [callableFeedUrl]);
143
+ }, [callableFeedUrl, resolvers]);
137
144
 
138
145
  return React.useMemo(() => {
139
146
  if (!callableFeedUrl || !feedUrl) {
@@ -1,5 +1,11 @@
1
1
  import { NativeModules, Platform } from "react-native";
2
2
 
3
+ export const isAndroidTablet = () => {
4
+ const { initialProps } = NativeModules.QuickBrickCommunicationModule;
5
+
6
+ return initialProps?.is_tablet;
7
+ };
8
+
3
9
  /**
4
10
  * Determines wether the given device is a tablet based on dimensions, orientation, and platform
5
11
  * @param {Object} dimensions - Dimensions object passed to the function
@@ -13,9 +19,7 @@ export const isTablet = (
13
19
  if (Platform?.OS === "ios") {
14
20
  return Platform?.isPad;
15
21
  } else if (Platform?.OS === "android") {
16
- const { initialProps } = NativeModules.QuickBrickCommunicationModule;
17
-
18
- return initialProps?.is_tablet;
22
+ return isAndroidTablet();
19
23
  }
20
24
 
21
25
  const { width } = dimensions || {};
@@ -14,7 +14,7 @@ import { HOOKS_EVENTS } from "../../appUtils/HooksManager/constants";
14
14
  import { getRiverFromRoute, getTargetRoute } from "../../navigationUtils";
15
15
  import { useConnectionInfo } from "../connection";
16
16
 
17
- import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
17
+ import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
18
18
  import { useNavbarState } from "../screen";
19
19
 
20
20
  export { useNavigation } from "./useNavigation";
@@ -127,11 +127,13 @@ export function isNavBarVisible(
127
127
 
128
128
  export const useBackHandler = (cb: () => boolean) => {
129
129
  useEffect(() => {
130
- BackHandler.addEventListener("hardwareBackPress", cb);
130
+ if (!isWeb()) {
131
+ const unsubscribe = BackHandler.addEventListener("hardwareBackPress", cb);
131
132
 
132
- return () => {
133
- BackHandler.removeEventListener("hardwareBackPress", cb);
134
- };
133
+ return () => {
134
+ unsubscribe.remove();
135
+ };
136
+ }
135
137
  }, [cb]);
136
138
  };
137
139
 
@@ -28,14 +28,19 @@ const isHookPathname = (pathname: string) => /^\/hooks\//.test(pathname);
28
28
 
29
29
  type VariousScreenData = LegacyNavigationScreenData | ZappRiver | ZappEntry;
30
30
 
31
- export const useRoute = (): {
31
+ export const useRoute = (
32
+ useLegacy = true
33
+ ): {
32
34
  screenData: VariousScreenData;
33
35
  pathname: string;
34
36
  } => {
35
37
  const pathname = usePathname() || "";
36
38
  const navigator = useNavigation();
39
+ const screenContext = useContext(ScreenDataContext);
37
40
 
38
- const screenDataContext = legacyScreenData(useContext(ScreenDataContext));
41
+ const screenDataContext = useLegacy
42
+ ? legacyScreenData(screenContext)
43
+ : screenContext;
39
44
 
40
45
  const { plugins, contentTypes, rivers } = usePickFromState([
41
46
  "plugins",
@@ -0,0 +1,8 @@
1
+ import { useRoute } from "./useRoute";
2
+ import { useMemo } from "react";
3
+
4
+ export const useScreenStateStore = () => {
5
+ const route = useRoute(false);
6
+
7
+ return useMemo(() => route.screenData["screenStateStore"], [route.pathname]);
8
+ };