react-router 0.0.0-experimental-5f08b33f → 0.0.0-experimental-ad6954b7

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # `react-router`
2
2
 
3
+ ## 6.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add's a new `redirectDocument()` function which allows users to specify that a redirect from a `loader`/`action` should trigger a document reload (via `window.location`) instead of attempting to navigate to the redirected location via React Router ([#10705](https://github.com/remix-run/react-router/pull/10705))
8
+
9
+ ### Patch Changes
10
+
11
+ - Ensure `useRevalidator` is referentially stable across re-renders if revalidations are not actively occurring ([#10707](https://github.com/remix-run/react-router/pull/10707))
12
+ - Updated dependencies:
13
+ - `@remix-run/router@1.8.0`
14
+
15
+ ## 6.14.2
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies:
20
+ - `@remix-run/router@1.7.2`
21
+
22
+ ## 6.14.1
23
+
24
+ ### Patch Changes
25
+
26
+ - Fix loop in `unstable_useBlocker` when used with an unstable blocker function ([#10652](https://github.com/remix-run/react-router/pull/10652))
27
+ - Fix issues with reused blockers on subsequent navigations ([#10656](https://github.com/remix-run/react-router/pull/10656))
28
+ - Updated dependencies:
29
+ - `@remix-run/router@1.7.1`
30
+
31
+ ## 6.14.0
32
+
33
+ ### Patch Changes
34
+
35
+ - Strip `basename` from locations provided to `unstable_useBlocker` functions to match `useLocation` ([#10573](https://github.com/remix-run/react-router/pull/10573))
36
+ - Fix `generatePath` when passed a numeric `0` value parameter ([#10612](https://github.com/remix-run/react-router/pull/10612))
37
+ - Fix `unstable_useBlocker` key issues in `StrictMode` ([#10573](https://github.com/remix-run/react-router/pull/10573))
38
+ - Fix `tsc --skipLibCheck:false` issues on React 17 ([#10622](https://github.com/remix-run/react-router/pull/10622))
39
+ - Upgrade `typescript` to 5.1 ([#10581](https://github.com/remix-run/react-router/pull/10581))
40
+ - Updated dependencies:
41
+ - `@remix-run/router@1.7.0`
42
+
43
+ ## 6.13.0
44
+
45
+ ### Minor Changes
46
+
47
+ - Move [`React.startTransition`](https://react.dev/reference/react/startTransition) usage behind a [future flag](https://reactrouter.com/en/main/guides/api-development-strategy) to avoid issues with existing incompatible `Suspense` usages. We recommend folks adopting this flag to be better compatible with React concurrent mode, but if you run into issues you can continue without the use of `startTransition` until v7. Issues usually boils down to creating net-new promises during the render cycle, so if you run into issues you should either lift your promise creation out of the render cycle or put it behind a `useMemo`. ([#10596](https://github.com/remix-run/react-router/pull/10596))
48
+
49
+ Existing behavior will no longer include `React.startTransition`:
50
+
51
+ ```jsx
52
+ <BrowserRouter>
53
+ <Routes>{/*...*/}</Routes>
54
+ </BrowserRouter>
55
+
56
+ <RouterProvider router={router} />
57
+ ```
58
+
59
+ If you wish to enable `React.startTransition`, pass the future flag to your component:
60
+
61
+ ```jsx
62
+ <BrowserRouter future={{ v7_startTransition: true }}>
63
+ <Routes>{/*...*/}</Routes>
64
+ </BrowserRouter>
65
+
66
+ <RouterProvider router={router} future={{ v7_startTransition: true }}/>
67
+ ```
68
+
69
+ ### Patch Changes
70
+
71
+ - Work around webpack/terser `React.startTransition` minification bug in production mode ([#10588](https://github.com/remix-run/react-router/pull/10588))
72
+
73
+ ## 6.12.1
74
+
75
+ > **Warning**
76
+ > Please use version `6.13.0` or later instead of `6.12.1`. This version suffers from a `webpack`/`terser` minification issue resulting in invalid minified code in your resulting production bundles which can cause issues in your application. See [#10579](https://github.com/remix-run/react-router/issues/10579) for more details.
77
+
78
+ ### Patch Changes
79
+
80
+ - Adjust feature detection of `React.startTransition` to fix webpack + react 17 compilation error ([#10569](https://github.com/remix-run/react-router/pull/10569))
81
+
3
82
  ## 6.12.0
4
83
 
5
84
  ### Minor Changes
package/dist/index.d.ts CHANGED
@@ -1,25 +1,25 @@
1
- import type { ActionFunction, ActionFunctionArgs, Blocker, BlockerFunction, Fetcher, HydrationState, JsonFunction, LoaderFunction, LoaderFunctionArgs, Location, Navigation, Params, ParamParseKey, Path, PathMatch, PathPattern, RedirectFunction, RelativeRoutingType, Router as RemixRouter, ShouldRevalidateFunction, To, InitialEntry, LazyRouteFunction, FutureConfig } from "@remix-run/router";
2
- import { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, resolvePath } from "@remix-run/router";
3
- import type { AwaitProps, MemoryRouterProps, NavigateProps, OutletProps, RouteProps, PathRouteProps, LayoutRouteProps, IndexRouteProps, RouterProps, RoutesProps, RouterProviderProps } from "./lib/components";
4
- import { createRoutesFromChildren, renderMatches, Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes } from "./lib/components";
5
- import type { DataRouteMatch, DataRouteObject, IndexRouteObject, Navigator, NavigateOptions, NonIndexRouteObject, RouteMatch, RouteObject } from "./lib/context";
1
+ import type { ActionFunction, ActionFunctionArgs, Blocker, BlockerFunction, Fetcher, HydrationState, InitialEntry, JsonFunction, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, Location, Navigation, ParamParseKey, Params, Path, PathMatch, PathPattern, RedirectFunction, RelativeRoutingType, Router as RemixRouter, FutureConfig as RouterFutureConfig, ShouldRevalidateFunction, To } from "@remix-run/router";
2
+ import { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, resolvePath } from "@remix-run/router";
3
+ import type { AwaitProps, FutureConfig, IndexRouteProps, LayoutRouteProps, MemoryRouterProps, NavigateProps, OutletProps, PathRouteProps, RouteProps, RouterProps, RouterProviderProps, RoutesProps } from "./lib/components";
4
+ import { Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes, createRoutesFromChildren, renderMatches } from "./lib/components";
5
+ import type { DataRouteMatch, DataRouteObject, IndexRouteObject, NavigateOptions, Navigator, NonIndexRouteObject, RouteMatch, RouteObject } from "./lib/context";
6
6
  import { DataRouterContext, DataRouterStateContext, LocationContext, NavigationContext, RouteContext } from "./lib/context";
7
7
  import type { NavigateFunction } from "./lib/hooks";
8
- import { useBlocker, useHref, useInRouterContext, useLocation, useMatch, useNavigationType, useNavigate, useOutlet, useOutletContext, useParams, useResolvedPath, useRoutes, useActionData, useAsyncError, useAsyncValue, useRouteId, useLoaderData, useMatches, useNavigation, useRevalidator, useRouteError, useRouteLoaderData, useRoutesImpl } from "./lib/hooks";
9
- declare type Hash = string;
10
- declare type Pathname = string;
11
- declare type Search = string;
12
- export type { ActionFunction, ActionFunctionArgs, AwaitProps, Blocker as unstable_Blocker, BlockerFunction as unstable_BlockerFunction, DataRouteMatch, DataRouteObject, Fetcher, Hash, IndexRouteObject, IndexRouteProps, JsonFunction, LazyRouteFunction, LayoutRouteProps, LoaderFunction, LoaderFunctionArgs, Location, MemoryRouterProps, NavigateFunction, NavigateOptions, NavigateProps, Navigation, Navigator, NonIndexRouteObject, OutletProps, Params, ParamParseKey, Path, PathMatch, Pathname, PathPattern, PathRouteProps, RedirectFunction, RelativeRoutingType, RouteMatch, RouteObject, RouteProps, RouterProps, RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, To, };
13
- export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, RouterProvider, Routes, createPath, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, defer, isRouteErrorResponse, generatePath, json, matchPath, matchRoutes, parsePath, redirect, renderMatches, resolvePath, useActionData, useAsyncError, useAsyncValue, useBlocker as unstable_useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, };
8
+ import { useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteId, useRouteLoaderData, useRoutes, useRoutesImpl } from "./lib/hooks";
9
+ type Hash = string;
10
+ type Pathname = string;
11
+ type Search = string;
12
+ export type { ActionFunction, ActionFunctionArgs, AwaitProps, DataRouteMatch, DataRouteObject, Fetcher, FutureConfig, Hash, IndexRouteObject, IndexRouteProps, JsonFunction, LayoutRouteProps, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, Location, MemoryRouterProps, NavigateFunction, NavigateOptions, NavigateProps, Navigation, Navigator, NonIndexRouteObject, OutletProps, ParamParseKey, Params, Path, PathMatch, PathPattern, PathRouteProps, Pathname, RedirectFunction, RelativeRoutingType, RouteMatch, RouteObject, RouteProps, RouterProps, RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, To, Blocker as unstable_Blocker, BlockerFunction as unstable_BlockerFunction, };
13
+ export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, RouterProvider, Routes, createPath, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, resolvePath, useBlocker as unstable_useBlocker, useActionData, useAsyncError, useAsyncValue, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, };
14
14
  declare function mapRouteProperties(route: RouteObject): Partial<RouteObject> & {
15
15
  hasErrorBoundary: boolean;
16
16
  };
17
17
  export declare function createMemoryRouter(routes: RouteObject[], opts?: {
18
18
  basename?: string;
19
- future?: Partial<Omit<FutureConfig, "v7_prependBasename">>;
19
+ future?: Partial<Omit<RouterFutureConfig, "v7_prependBasename">>;
20
20
  hydrationData?: HydrationState;
21
21
  initialEntries?: InitialEntry[];
22
22
  initialIndex?: number;
23
23
  }): RemixRouter;
24
24
  /** @internal */
25
- export { NavigationContext as UNSAFE_NavigationContext, LocationContext as UNSAFE_LocationContext, RouteContext as UNSAFE_RouteContext, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, mapRouteProperties as UNSAFE_mapRouteProperties, useRouteId as UNSAFE_useRouteId, useRoutesImpl as UNSAFE_useRoutesImpl, };
25
+ export { DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, mapRouteProperties as UNSAFE_mapRouteProperties, useRouteId as UNSAFE_useRouteId, useRoutesImpl as UNSAFE_useRoutesImpl, };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v0.0.0-experimental-5f08b33f
2
+ * React Router v0.0.0-experimental-ad6954b7
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -9,8 +9,8 @@
9
9
  * @license MIT
10
10
  */
11
11
  import * as React from 'react';
12
- import { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_getPathContributingMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, isRouteErrorResponse, createMemoryHistory, stripBasename, AbortedDeferredError, createRouter } from '@remix-run/router';
13
- export { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, resolvePath } from '@remix-run/router';
12
+ import { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_getPathContributingMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, stripBasename, IDLE_BLOCKER, isRouteErrorResponse, createMemoryHistory, AbortedDeferredError, createRouter } from '@remix-run/router';
13
+ export { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, resolvePath } from '@remix-run/router';
14
14
 
15
15
  function _extends() {
16
16
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -585,14 +585,13 @@ function _renderMatches(matches, parentMatches, dataRouterState) {
585
585
  }) : getChildren();
586
586
  }, null);
587
587
  }
588
- var DataRouterHook;
589
- (function (DataRouterHook) {
588
+ var DataRouterHook = /*#__PURE__*/function (DataRouterHook) {
590
589
  DataRouterHook["UseBlocker"] = "useBlocker";
591
590
  DataRouterHook["UseRevalidator"] = "useRevalidator";
592
591
  DataRouterHook["UseNavigateStable"] = "useNavigate";
593
- })(DataRouterHook || (DataRouterHook = {}));
594
- var DataRouterStateHook;
595
- (function (DataRouterStateHook) {
592
+ return DataRouterHook;
593
+ }(DataRouterHook || {});
594
+ var DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {
596
595
  DataRouterStateHook["UseBlocker"] = "useBlocker";
597
596
  DataRouterStateHook["UseLoaderData"] = "useLoaderData";
598
597
  DataRouterStateHook["UseActionData"] = "useActionData";
@@ -603,7 +602,8 @@ var DataRouterStateHook;
603
602
  DataRouterStateHook["UseRevalidator"] = "useRevalidator";
604
603
  DataRouterStateHook["UseNavigateStable"] = "useNavigate";
605
604
  DataRouterStateHook["UseRouteId"] = "useRouteId";
606
- })(DataRouterStateHook || (DataRouterStateHook = {}));
605
+ return DataRouterStateHook;
606
+ }(DataRouterStateHook || {});
607
607
  function getDataRouterConsoleError(hookName) {
608
608
  return hookName + " must be used within a data router. See https://reactrouter.com/routers/picking-a-router.";
609
609
  }
@@ -654,10 +654,10 @@ function useNavigation() {
654
654
  function useRevalidator() {
655
655
  let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator);
656
656
  let state = useDataRouterState(DataRouterStateHook.UseRevalidator);
657
- return {
657
+ return React.useMemo(() => ({
658
658
  revalidate: dataRouterContext.router.revalidate,
659
659
  state: state.revalidation
660
- };
660
+ }), [dataRouterContext.router.revalidate, state.revalidation]);
661
661
  }
662
662
 
663
663
  /**
@@ -764,21 +764,59 @@ let blockerId = 0;
764
764
  */
765
765
  function useBlocker(shouldBlock) {
766
766
  let {
767
- router
767
+ router,
768
+ basename
768
769
  } = useDataRouterContext(DataRouterHook.UseBlocker);
769
770
  let state = useDataRouterState(DataRouterStateHook.UseBlocker);
770
- let [blockerKey] = React.useState(() => String(++blockerId));
771
- let blockerFunction = React.useCallback(args => {
772
- return typeof shouldBlock === "function" ? !!shouldBlock(args) : !!shouldBlock;
773
- }, [shouldBlock]);
774
- let blocker = router.getBlocker(blockerKey, blockerFunction);
771
+ let [blockerKey, setBlockerKey] = React.useState("");
772
+ let blockerFunction = React.useCallback(arg => {
773
+ if (typeof shouldBlock !== "function") {
774
+ return !!shouldBlock;
775
+ }
776
+ if (basename === "/") {
777
+ return shouldBlock(arg);
778
+ }
775
779
 
776
- // Cleanup on unmount
777
- React.useEffect(() => () => router.deleteBlocker(blockerKey), [router, blockerKey]);
780
+ // If they provided us a function and we've got an active basename, strip
781
+ // it from the locations we expose to the user to match the behavior of
782
+ // useLocation
783
+ let {
784
+ currentLocation,
785
+ nextLocation,
786
+ historyAction
787
+ } = arg;
788
+ return shouldBlock({
789
+ currentLocation: _extends({}, currentLocation, {
790
+ pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname
791
+ }),
792
+ nextLocation: _extends({}, nextLocation, {
793
+ pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname
794
+ }),
795
+ historyAction
796
+ });
797
+ }, [basename, shouldBlock]);
798
+
799
+ // This effect is in charge of blocker key assignment and deletion (which is
800
+ // tightly coupled to the key)
801
+ React.useEffect(() => {
802
+ let key = String(++blockerId);
803
+ setBlockerKey(key);
804
+ return () => router.deleteBlocker(key);
805
+ }, [router]);
778
806
 
779
- // Prefer the blocker from state since DataRouterContext is memoized so this
780
- // ensures we update on blocker state updates
781
- return state.blockers.get(blockerKey) || blocker;
807
+ // This effect handles assigning the blockerFunction. This is to handle
808
+ // unstable blocker function identities, and happens only after the prior
809
+ // effect so we don't get an orphaned blockerFunction in the router with a
810
+ // key of "". Until then we just have the IDLE_BLOCKER.
811
+ React.useEffect(() => {
812
+ if (blockerKey !== "") {
813
+ router.getBlocker(blockerKey, blockerFunction);
814
+ }
815
+ }, [router, blockerKey, blockerFunction]);
816
+
817
+ // Prefer the blocker from `state` not `router.state` since DataRouterContext
818
+ // is memoized so this ensures we update on blocker state updates
819
+ return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;
782
820
  }
783
821
 
784
822
  /**
@@ -821,20 +859,48 @@ function warningOnce(key, cond, message) {
821
859
  }
822
860
  }
823
861
 
862
+ /**
863
+ Webpack + React 17 fails to compile on any of the following because webpack
864
+ complains that `startTransition` doesn't exist in `React`:
865
+ * import { startTransition } from "react"
866
+ * import * as React from from "react";
867
+ "startTransition" in React ? React.startTransition(() => setState()) : setState()
868
+ * import * as React from from "react";
869
+ "startTransition" in React ? React["startTransition"](() => setState()) : setState()
870
+
871
+ Moving it to a constant such as the following solves the Webpack/React 17 issue:
872
+ * import * as React from from "react";
873
+ const START_TRANSITION = "startTransition";
874
+ START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()
875
+
876
+ However, that introduces webpack/terser minification issues in production builds
877
+ in React 18 where minification/obfuscation ends up removing the call of
878
+ React.startTransition entirely from the first half of the ternary. Grabbing
879
+ this exported reference once up front resolves that issue.
880
+
881
+ See https://github.com/remix-run/react-router/issues/10579
882
+ */
883
+ const START_TRANSITION = "startTransition";
884
+ const startTransitionImpl = React[START_TRANSITION];
885
+
824
886
  /**
825
887
  * Given a Remix Router instance, render the appropriate UI
826
888
  */
827
889
  function RouterProvider(_ref) {
828
890
  let {
829
891
  fallbackElement,
830
- router
892
+ router,
893
+ future
831
894
  } = _ref;
832
895
  // Need to use a layout effect here so we are subscribed early enough to
833
896
  // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
834
897
  let [state, setStateImpl] = React.useState(router.state);
898
+ let {
899
+ v7_startTransition
900
+ } = future || {};
835
901
  let setState = React.useCallback(newState => {
836
- "startTransition" in React ? React.startTransition(() => setStateImpl(newState)) : setStateImpl(newState);
837
- }, [setStateImpl]);
902
+ v7_startTransition && startTransitionImpl ? startTransitionImpl(() => setStateImpl(newState)) : setStateImpl(newState);
903
+ }, [setStateImpl, v7_startTransition]);
838
904
  React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
839
905
  let navigator = React.useMemo(() => {
840
906
  return {
@@ -897,7 +963,8 @@ function MemoryRouter(_ref3) {
897
963
  basename,
898
964
  children,
899
965
  initialEntries,
900
- initialIndex
966
+ initialIndex,
967
+ future
901
968
  } = _ref3;
902
969
  let historyRef = React.useRef();
903
970
  if (historyRef.current == null) {
@@ -912,9 +979,12 @@ function MemoryRouter(_ref3) {
912
979
  action: history.action,
913
980
  location: history.location
914
981
  });
982
+ let {
983
+ v7_startTransition
984
+ } = future || {};
915
985
  let setState = React.useCallback(newState => {
916
- "startTransition" in React ? React.startTransition(() => setStateImpl(newState)) : setStateImpl(newState);
917
- }, [setStateImpl]);
986
+ v7_startTransition && startTransitionImpl ? startTransitionImpl(() => setStateImpl(newState)) : setStateImpl(newState);
987
+ }, [setStateImpl, v7_startTransition]);
918
988
  React.useLayoutEffect(() => history.listen(setState), [history, setState]);
919
989
  return /*#__PURE__*/React.createElement(Router, {
920
990
  basename: basename,
@@ -1072,12 +1142,12 @@ function Await(_ref7) {
1072
1142
  errorElement: errorElement
1073
1143
  }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));
1074
1144
  }
1075
- var AwaitRenderStatus;
1076
- (function (AwaitRenderStatus) {
1145
+ var AwaitRenderStatus = /*#__PURE__*/function (AwaitRenderStatus) {
1077
1146
  AwaitRenderStatus[AwaitRenderStatus["pending"] = 0] = "pending";
1078
1147
  AwaitRenderStatus[AwaitRenderStatus["success"] = 1] = "success";
1079
1148
  AwaitRenderStatus[AwaitRenderStatus["error"] = 2] = "error";
1080
- })(AwaitRenderStatus || (AwaitRenderStatus = {}));
1149
+ return AwaitRenderStatus;
1150
+ }(AwaitRenderStatus || {});
1081
1151
  const neverSettledPromise = new Promise(() => {});
1082
1152
  class AwaitErrorBoundary extends React.Component {
1083
1153
  constructor(props) {