react-router 0.0.0-experimental-7f486334 → 0.0.0-experimental-b24023f3
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 +17 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +79 -17
- package/dist/index.js.map +1 -1
- package/dist/lib/components.d.ts +4 -0
- package/dist/lib/context.d.ts +4 -0
- package/dist/lib/hooks.d.ts +2 -2
- package/dist/main.js +1 -1
- package/dist/react-router.development.js +74 -16
- package/dist/react-router.development.js.map +1 -1
- package/dist/react-router.production.min.js +2 -2
- package/dist/react-router.production.min.js.map +1 -1
- package/dist/umd/react-router.development.js +91 -29
- package/dist/umd/react-router.development.js.map +1 -1
- package/dist/umd/react-router.production.min.js +2 -2
- package/dist/umd/react-router.production.min.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# `react-router`
|
|
2
2
|
|
|
3
|
+
## 6.19.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add `unstable_flushSync` option to `useNavigate`/`useSumbit`/`fetcher.load`/`fetcher.submit` to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates ([#11005](https://github.com/remix-run/react-router/pull/11005))
|
|
8
|
+
- Remove the `unstable_` prefix from the [`useBlocker`](https://reactrouter.com/en/main/hooks/use-blocker) hook as it's been in use for enough time that we are confident in the API. We do not plan to remove the prefix from `unstable_usePrompt` due to differences in how browsers handle `window.confirm` that prevent React Router from guaranteeing consistent/correct behavior. ([#10991](https://github.com/remix-run/react-router/pull/10991))
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Fix `useActionData` so it returns proper contextual action data and not _any_ action data in the tree ([#11023](https://github.com/remix-run/react-router/pull/11023))
|
|
13
|
+
- Fix bug in `useResolvedPath` that would cause `useResolvedPath(".")` in a splat route to lose the splat portion of the URL path. ([#10983](https://github.com/remix-run/react-router/pull/10983))
|
|
14
|
+
|
|
15
|
+
- ⚠️ This fixes a quite long-standing bug specifically for `"."` paths inside a splat route which incorrectly dropped the splat portion of the URL. If you are relative routing via `"."` inside a splat route in your application you should double check that your logic is not relying on this buggy behavior and update accordingly.
|
|
16
|
+
|
|
17
|
+
- Updated dependencies:
|
|
18
|
+
- `@remix-run/router@1.12.0`
|
|
19
|
+
|
|
3
20
|
## 6.18.0
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActionFunction, ActionFunctionArgs, Blocker, BlockerFunction, ErrorResponse, Fetcher, HydrationState, InitialEntry, JsonFunction, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, Location, Navigation, ParamParseKey, Params, Path, PathMatch, PathPattern, RedirectFunction, RelativeRoutingType, Router as RemixRouter, FutureConfig as RouterFutureConfig, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, To, UIMatch } from "@remix-run/router";
|
|
1
|
+
import type { ActionFunction, ActionFunctionArgs, Blocker, BlockerFunction, ErrorResponse, Fetcher, HydrationState, InitialEntry, JsonFunction, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, Location, Navigation, ParamParseKey, Params, Path, PathMatch, PathParam, PathPattern, RedirectFunction, RelativeRoutingType, Router as RemixRouter, FutureConfig as RouterFutureConfig, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, To, UIMatch } from "@remix-run/router";
|
|
2
2
|
import { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, resolvePath } from "@remix-run/router";
|
|
3
3
|
import type { AwaitProps, FutureConfig, IndexRouteProps, LayoutRouteProps, MemoryRouterProps, NavigateProps, OutletProps, PathRouteProps, RouteProps, RouterProps, RouterProviderProps, RoutesProps } from "./lib/components";
|
|
4
4
|
import { Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes, createRoutesFromChildren, renderMatches } from "./lib/components";
|
|
@@ -9,7 +9,7 @@ import { useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useIn
|
|
|
9
9
|
type Hash = string;
|
|
10
10
|
type Pathname = string;
|
|
11
11
|
type Search = string;
|
|
12
|
-
export type { ActionFunction, ActionFunctionArgs, AwaitProps, DataRouteMatch, DataRouteObject, ErrorResponse, 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, ShouldRevalidateFunctionArgs, To, UIMatch, Blocker as unstable_Blocker, BlockerFunction as unstable_BlockerFunction, };
|
|
12
|
+
export type { ActionFunction, ActionFunctionArgs, AwaitProps, DataRouteMatch, DataRouteObject, ErrorResponse, Fetcher, FutureConfig, Hash, IndexRouteObject, IndexRouteProps, JsonFunction, LayoutRouteProps, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, Location, MemoryRouterProps, NavigateFunction, NavigateOptions, NavigateProps, Navigation, Navigator, NonIndexRouteObject, OutletProps, ParamParseKey, Params, Path, PathMatch, PathParam, PathPattern, PathRouteProps, Pathname, RedirectFunction, RelativeRoutingType, RouteMatch, RouteObject, RouteProps, RouterProps, RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, To, UIMatch, Blocker as unstable_Blocker, BlockerFunction as unstable_BlockerFunction, };
|
|
13
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, 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;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React Router v0.0.0-experimental-
|
|
2
|
+
* React Router v0.0.0-experimental-b24023f3
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
11
|
import * as React from 'react';
|
|
12
|
-
import { UNSAFE_invariant, joinPaths, matchPath,
|
|
12
|
+
import { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_getResolveToMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, UNSAFE_convertRouteMatchToUiMatch, stripBasename, IDLE_BLOCKER, isRouteErrorResponse, createMemoryHistory, AbortedDeferredError, createRouter } from '@remix-run/router';
|
|
13
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() {
|
|
@@ -212,7 +212,7 @@ function useNavigateUnstable() {
|
|
|
212
212
|
let {
|
|
213
213
|
pathname: locationPathname
|
|
214
214
|
} = useLocation();
|
|
215
|
-
let routePathnamesJson = JSON.stringify(
|
|
215
|
+
let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches));
|
|
216
216
|
let activeRef = React.useRef(false);
|
|
217
217
|
useIsomorphicLayoutEffect(() => {
|
|
218
218
|
activeRef.current = true;
|
|
@@ -301,10 +301,7 @@ function useResolvedPath(to, _temp2) {
|
|
|
301
301
|
let {
|
|
302
302
|
pathname: locationPathname
|
|
303
303
|
} = useLocation();
|
|
304
|
-
|
|
305
|
-
// Use the full pathname for the leaf match so we include splat values
|
|
306
|
-
// for "." links
|
|
307
|
-
let routePathnamesJson = JSON.stringify(UNSAFE_getPathContributingMatches(matches).map((match, idx) => idx === matches.length - 1 ? match.pathname : match.pathnameBase));
|
|
304
|
+
let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches));
|
|
308
305
|
return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
|
|
309
306
|
}
|
|
310
307
|
|
|
@@ -321,7 +318,7 @@ function useRoutes(routes, locationArg) {
|
|
|
321
318
|
}
|
|
322
319
|
|
|
323
320
|
// Internal implementation with accept optional param for RouterProvider usage
|
|
324
|
-
function useRoutesImpl(routes, locationArg, dataRouterState) {
|
|
321
|
+
function useRoutesImpl(routes, locationArg, dataRouterState, future) {
|
|
325
322
|
!useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
|
|
326
323
|
// router loaded. We can help them understand how to avoid that.
|
|
327
324
|
"useRoutes() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
|
|
@@ -387,7 +384,7 @@ function useRoutesImpl(routes, locationArg, dataRouterState) {
|
|
|
387
384
|
pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase,
|
|
388
385
|
// Re-encode pathnames that were decoded inside matchRoutes
|
|
389
386
|
navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])
|
|
390
|
-
})), parentMatches, dataRouterState);
|
|
387
|
+
})), parentMatches, dataRouterState, future);
|
|
391
388
|
|
|
392
389
|
// When a user passes in a `locationArg`, the associated routes need to
|
|
393
390
|
// be wrapped in a new `LocationContext.Provider` in order for `useLocation`
|
|
@@ -509,7 +506,7 @@ function RenderedRoute(_ref) {
|
|
|
509
506
|
value: routeContext
|
|
510
507
|
}, children);
|
|
511
508
|
}
|
|
512
|
-
function _renderMatches(matches, parentMatches, dataRouterState) {
|
|
509
|
+
function _renderMatches(matches, parentMatches, dataRouterState, future) {
|
|
513
510
|
var _dataRouterState2;
|
|
514
511
|
if (parentMatches === void 0) {
|
|
515
512
|
parentMatches = [];
|
|
@@ -517,6 +514,9 @@ function _renderMatches(matches, parentMatches, dataRouterState) {
|
|
|
517
514
|
if (dataRouterState === void 0) {
|
|
518
515
|
dataRouterState = null;
|
|
519
516
|
}
|
|
517
|
+
if (future === void 0) {
|
|
518
|
+
future = null;
|
|
519
|
+
}
|
|
520
520
|
if (matches == null) {
|
|
521
521
|
var _dataRouterState;
|
|
522
522
|
if ((_dataRouterState = dataRouterState) != null && _dataRouterState.errors) {
|
|
@@ -536,18 +536,63 @@ function _renderMatches(matches, parentMatches, dataRouterState) {
|
|
|
536
536
|
!(errorIndex >= 0) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "Could not find a matching route for errors on route IDs: " + Object.keys(errors).join(",")) : UNSAFE_invariant(false) : void 0;
|
|
537
537
|
renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
|
|
538
538
|
}
|
|
539
|
+
|
|
540
|
+
// If we're in a partial hydration mode, detect if we need to render down to
|
|
541
|
+
// a given Fallback while we load the rest of the hydration data
|
|
542
|
+
let renderFallback = false;
|
|
543
|
+
let fallbackIndex = -1;
|
|
544
|
+
if (dataRouterState && future && future.v7_partialHydration) {
|
|
545
|
+
for (let i = 0; i < renderedMatches.length; i++) {
|
|
546
|
+
let match = renderedMatches[i];
|
|
547
|
+
// Track the deepest fallback up until the first route without data
|
|
548
|
+
if (match.route.Fallback || match.route.fallbackElement) {
|
|
549
|
+
fallbackIndex = i;
|
|
550
|
+
}
|
|
551
|
+
if (match.route.loader && match.route.id && dataRouterState.loaderData[match.route.id] === undefined && (!dataRouterState.errors || dataRouterState.errors[match.route.id] === undefined)) {
|
|
552
|
+
// TODO:
|
|
553
|
+
// TODO: Add unit tests for this error flow!
|
|
554
|
+
// TODO:
|
|
555
|
+
|
|
556
|
+
// We found the first route without data/errors which means it's loader
|
|
557
|
+
// still needs to run. Flag that we need to render a fallback and
|
|
558
|
+
// render up until the appropriate fallback
|
|
559
|
+
renderFallback = true;
|
|
560
|
+
if (fallbackIndex >= 0) {
|
|
561
|
+
renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
|
|
562
|
+
} else {
|
|
563
|
+
renderedMatches = [renderedMatches[0]];
|
|
564
|
+
}
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
539
569
|
return renderedMatches.reduceRight((outlet, match, index) => {
|
|
540
|
-
|
|
541
|
-
|
|
570
|
+
// Only data routers handle errors/fallbacks
|
|
571
|
+
let error;
|
|
572
|
+
let fallback = false;
|
|
542
573
|
let errorElement = null;
|
|
574
|
+
let fallbackElement = null;
|
|
543
575
|
if (dataRouterState) {
|
|
576
|
+
error = errors && match.route.id ? errors[match.route.id] : null;
|
|
544
577
|
errorElement = match.route.errorElement || defaultErrorElement;
|
|
578
|
+
if (renderFallback) {
|
|
579
|
+
if (fallbackIndex < 0 && index === 0) {
|
|
580
|
+
warningOnce("route-fallback", false, "No `Fallback` element provided to render during initial hydration");
|
|
581
|
+
fallback = true;
|
|
582
|
+
fallbackElement = null;
|
|
583
|
+
} else if (fallbackIndex === index) {
|
|
584
|
+
fallback = true;
|
|
585
|
+
fallbackElement = match.route.fallbackElement || null;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
545
588
|
}
|
|
546
589
|
let matches = parentMatches.concat(renderedMatches.slice(0, index + 1));
|
|
547
590
|
let getChildren = () => {
|
|
548
591
|
let children;
|
|
549
592
|
if (error) {
|
|
550
593
|
children = errorElement;
|
|
594
|
+
} else if (fallback) {
|
|
595
|
+
children = fallbackElement;
|
|
551
596
|
} else if (match.route.Component) {
|
|
552
597
|
// Note: This is a de-optimized path since React won't re-use the
|
|
553
598
|
// ReactElement since it's identity changes with each new
|
|
@@ -701,9 +746,8 @@ function useRouteLoaderData(routeId) {
|
|
|
701
746
|
*/
|
|
702
747
|
function useActionData() {
|
|
703
748
|
let state = useDataRouterState(DataRouterStateHook.UseActionData);
|
|
704
|
-
let
|
|
705
|
-
|
|
706
|
-
return Object.values((state == null ? void 0 : state.actionData) || {})[0];
|
|
749
|
+
let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);
|
|
750
|
+
return state.actionData ? state.actionData[routeId] : undefined;
|
|
707
751
|
}
|
|
708
752
|
|
|
709
753
|
/**
|
|
@@ -895,6 +939,11 @@ function RouterProvider(_ref) {
|
|
|
895
939
|
// Need to use a layout effect here so we are subscribed early enough to
|
|
896
940
|
// pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
|
|
897
941
|
React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
|
|
942
|
+
React.useEffect(() => {
|
|
943
|
+
process.env.NODE_ENV !== "production" ? UNSAFE_warning(fallbackElement == null || !router.future.v7_partialHydration, "`<RouterProvider fallbackElement>` is deprecated when using `v7_partialHydration`") : void 0;
|
|
944
|
+
// Only log this once on initial mount
|
|
945
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
946
|
+
}, []);
|
|
898
947
|
let navigator = React.useMemo(() => {
|
|
899
948
|
return {
|
|
900
949
|
createHref: router.createHref,
|
|
@@ -936,15 +985,17 @@ function RouterProvider(_ref) {
|
|
|
936
985
|
navigator: navigator
|
|
937
986
|
}, state.initialized ? /*#__PURE__*/React.createElement(DataRoutes, {
|
|
938
987
|
routes: router.routes,
|
|
988
|
+
future: router.future,
|
|
939
989
|
state: state
|
|
940
990
|
}) : fallbackElement))), null);
|
|
941
991
|
}
|
|
942
992
|
function DataRoutes(_ref2) {
|
|
943
993
|
let {
|
|
944
994
|
routes,
|
|
995
|
+
future,
|
|
945
996
|
state
|
|
946
997
|
} = _ref2;
|
|
947
|
-
return useRoutesImpl(routes, undefined, state);
|
|
998
|
+
return useRoutesImpl(routes, undefined, state, future);
|
|
948
999
|
}
|
|
949
1000
|
/**
|
|
950
1001
|
* A `<Router>` that stores all entries in memory.
|
|
@@ -1017,7 +1068,7 @@ function Navigate(_ref4) {
|
|
|
1017
1068
|
|
|
1018
1069
|
// Resolve the path outside of the effect so that when effects run twice in
|
|
1019
1070
|
// StrictMode they navigate to the same place
|
|
1020
|
-
let path = resolveTo(to,
|
|
1071
|
+
let path = resolveTo(to, UNSAFE_getResolveToMatches(matches), locationPathname, relative === "path");
|
|
1021
1072
|
let jsonPath = JSON.stringify(path);
|
|
1022
1073
|
React.useEffect(() => navigate(JSON.parse(jsonPath), {
|
|
1023
1074
|
replace,
|
|
@@ -1321,6 +1372,17 @@ function mapRouteProperties(route) {
|
|
|
1321
1372
|
Component: undefined
|
|
1322
1373
|
});
|
|
1323
1374
|
}
|
|
1375
|
+
if (route.Fallback) {
|
|
1376
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1377
|
+
if (route.fallbackElement) {
|
|
1378
|
+
process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, "You should not include both `Fallback` and `fallbackElement` on your route - " + "`Fallback` will be used.") : void 0;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
Object.assign(updates, {
|
|
1382
|
+
fallbackElement: /*#__PURE__*/React.createElement(route.Fallback),
|
|
1383
|
+
Fallback: undefined
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1324
1386
|
if (route.ErrorBoundary) {
|
|
1325
1387
|
if (process.env.NODE_ENV !== "production") {
|
|
1326
1388
|
if (route.errorElement) {
|