react-router-dom 6.10.0 → 6.11.0-pre.1
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 +31 -0
- package/LICENSE.md +3 -2
- package/dist/dom.d.ts +3 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +71 -41
- package/dist/index.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/react-router-dom.development.js +71 -41
- package/dist/react-router-dom.development.js.map +1 -1
- package/dist/react-router-dom.production.min.js +2 -2
- package/dist/react-router-dom.production.min.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +22 -9
- package/dist/server.mjs +23 -10
- package/dist/umd/react-router-dom.development.js +72 -38
- package/dist/umd/react-router-dom.development.js.map +1 -1
- package/dist/umd/react-router-dom.production.min.js +2 -2
- package/dist/umd/react-router-dom.production.min.js.map +1 -1
- package/package.json +3 -3
- package/server.d.ts +1 -1
- package/server.js +22 -9
- package/server.mjs +23 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# `react-router-dom`
|
|
2
2
|
|
|
3
|
+
## 6.11.0-pre.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add static prop to `StaticRouterProvider`'s internal `Router` component ([#10401](https://github.com/remix-run/react-router/pull/10401))
|
|
8
|
+
- Updated dependencies:
|
|
9
|
+
- `react-router@6.11.0-pre.1`
|
|
10
|
+
|
|
11
|
+
## 6.11.0-pre.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- - Enable relative routing in the `@remix-run/router` when providing a source route ID from which the path is relative to: ([#10336](https://github.com/remix-run/react-router/pull/10336))
|
|
16
|
+
|
|
17
|
+
- Example: `router.navigate("../path", { fromRouteId: "some-route" })`.
|
|
18
|
+
- This also applies to `router.fetch` which already receives a source route ID
|
|
19
|
+
|
|
20
|
+
- Introduce a new `@remix-run/router` `future.v7_prependBasename` flag to enable `basename` prefixing to all paths coming into `router.navigate` and `router.fetch`.
|
|
21
|
+
- Previously the `basename` was prepended in the React Router layer, but now that relative routing is being handled by the router we need prepend the `basename` _after_ resolving any relative paths
|
|
22
|
+
- This also enables `basename` support in `useFetcher` as well
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Fix inadvertent re-renders when using `Component` instead of `element` on a route definition ([#10287](https://github.com/remix-run/react-router/pull/10287))
|
|
27
|
+
- Fail gracefully on `<Link to="//">` and other invalid URL values ([#10367](https://github.com/remix-run/react-router/pull/10367))
|
|
28
|
+
- Switched from `useSyncExternalStore` to `useState` for internal `@remix-run/router` router state syncing in `<RouterProvider>`. We found some [subtle bugs](https://codesandbox.io/s/use-sync-external-store-loop-9g7b81) where router state updates got propagated _before_ other normal `useState` updates, which could lead to footguns in `useEffect` calls. ([#10377](https://github.com/remix-run/react-router/pull/10377))
|
|
29
|
+
- When using a `RouterProvider`, `useNavigate`/`useSubmit`/`fetcher.submit` are now stable across location changes, since we can handle relative routing via the `@remix-run/router` instance and get rid of our dependence on `useLocation()`. When using `BrowserRouter`, these hooks remain unstable across location changes because they still rely on `useLocation()`. ([#10336](https://github.com/remix-run/react-router/pull/10336))
|
|
30
|
+
- Updated dependencies:
|
|
31
|
+
- `react-router@6.11.0-pre.0`
|
|
32
|
+
- `@remix-run/router@1.6.0-pre.0`
|
|
33
|
+
|
|
3
34
|
## 6.10.0
|
|
4
35
|
|
|
5
36
|
### Minor Changes
|
package/LICENSE.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) React Training 2015-2019
|
|
4
|
-
Copyright (c) Remix Software 2020-
|
|
3
|
+
Copyright (c) React Training LLC 2015-2019
|
|
4
|
+
Copyright (c) Remix Software Inc. 2020-2021
|
|
5
|
+
Copyright (c) Shopify Inc. 2022-2023
|
|
5
6
|
|
|
6
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
8
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/dom.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { FormEncType, HTMLFormMethod } from "@remix-run/router";
|
|
2
|
-
import type { RelativeRoutingType } from "react-router";
|
|
1
|
+
import type { FormEncType, HTMLFormMethod, RelativeRoutingType } from "@remix-run/router";
|
|
3
2
|
export declare const defaultMethod: HTMLFormMethod;
|
|
4
3
|
export declare function isHtmlElement(object: any): object is HTMLElement;
|
|
5
4
|
export declare function isButtonElement(object: any): object is HTMLButtonElement;
|
|
@@ -41,9 +40,6 @@ export interface SubmitOptions {
|
|
|
41
40
|
/**
|
|
42
41
|
* The action URL path used to submit the form. Overrides `<form action>`.
|
|
43
42
|
* Defaults to the path of the current route.
|
|
44
|
-
*
|
|
45
|
-
* Note: It is assumed the path is already resolved. If you need to resolve a
|
|
46
|
-
* relative path, use `useFormAction`.
|
|
47
43
|
*/
|
|
48
44
|
action?: string;
|
|
49
45
|
/**
|
|
@@ -71,8 +67,8 @@ export interface SubmitOptions {
|
|
|
71
67
|
}
|
|
72
68
|
export declare function getFormSubmissionInfo(target: HTMLFormElement | HTMLButtonElement | HTMLInputElement | FormData | URLSearchParams | {
|
|
73
69
|
[name: string]: string;
|
|
74
|
-
} | null,
|
|
75
|
-
|
|
70
|
+
} | null, options: SubmitOptions, basename: string): {
|
|
71
|
+
action: string | null;
|
|
76
72
|
method: string;
|
|
77
73
|
encType: string;
|
|
78
74
|
formData: FormData;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,13 +12,13 @@ export { createSearchParams };
|
|
|
12
12
|
export type { ActionFunction, ActionFunctionArgs, AwaitProps, unstable_Blocker, 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, } from "react-router";
|
|
13
13
|
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, RouterProvider, Routes, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, defer, isRouteErrorResponse, generatePath, json, matchPath, matchRoutes, parsePath, redirect, renderMatches, resolvePath, useActionData, useAsyncError, useAsyncValue, unstable_useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, } from "react-router";
|
|
14
14
|
/** @internal */
|
|
15
|
-
export { UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_NavigationContext, UNSAFE_LocationContext, UNSAFE_RouteContext, } from "react-router";
|
|
15
|
+
export { UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_NavigationContext, UNSAFE_LocationContext, UNSAFE_RouteContext, UNSAFE_useRouteId, } from "react-router";
|
|
16
16
|
declare global {
|
|
17
17
|
var __staticRouterHydrationData: HydrationState | undefined;
|
|
18
18
|
}
|
|
19
19
|
interface DOMRouterOpts {
|
|
20
20
|
basename?: string;
|
|
21
|
-
future?: FutureConfig
|
|
21
|
+
future?: Partial<Omit<FutureConfig, "v7_prependBasename">>;
|
|
22
22
|
hydrationData?: HydrationState;
|
|
23
23
|
window?: Window;
|
|
24
24
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React Router DOM v6.
|
|
2
|
+
* React Router DOM v6.11.0-pre.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
11
|
import * as React from 'react';
|
|
12
|
-
import {
|
|
13
|
-
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, RouterProvider, Routes, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, renderMatches, resolvePath, unstable_useBlocker, useActionData, useAsyncError, useAsyncValue, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes } from 'react-router';
|
|
14
|
-
import { createRouter, createBrowserHistory, createHashHistory, ErrorResponse,
|
|
12
|
+
import { UNSAFE_mapRouteProperties, Router, UNSAFE_NavigationContext, useHref, useResolvedPath, useLocation, UNSAFE_DataRouterStateContext, useNavigate, createPath, UNSAFE_useRouteId, UNSAFE_RouteContext, useMatches, useNavigation, unstable_useBlocker, UNSAFE_DataRouterContext } from 'react-router';
|
|
13
|
+
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, RouterProvider, Routes, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, UNSAFE_LocationContext, UNSAFE_NavigationContext, UNSAFE_RouteContext, UNSAFE_useRouteId, createMemoryRouter, createPath, createRoutesFromChildren, createRoutesFromElements, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, renderMatches, resolvePath, unstable_useBlocker, useActionData, useAsyncError, useAsyncValue, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes } from 'react-router';
|
|
14
|
+
import { stripBasename, createRouter, createBrowserHistory, createHashHistory, ErrorResponse, UNSAFE_warning, UNSAFE_invariant, joinPaths } from '@remix-run/router';
|
|
15
15
|
|
|
16
16
|
function _extends() {
|
|
17
17
|
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
@@ -117,16 +117,26 @@ function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
|
|
|
117
117
|
|
|
118
118
|
return searchParams;
|
|
119
119
|
}
|
|
120
|
-
function getFormSubmissionInfo(target,
|
|
120
|
+
function getFormSubmissionInfo(target, options, basename) {
|
|
121
121
|
let method;
|
|
122
|
-
let action;
|
|
122
|
+
let action = null;
|
|
123
123
|
let encType;
|
|
124
124
|
let formData;
|
|
125
125
|
|
|
126
126
|
if (isFormElement(target)) {
|
|
127
127
|
let submissionTrigger = options.submissionTrigger;
|
|
128
|
+
|
|
129
|
+
if (options.action) {
|
|
130
|
+
action = options.action;
|
|
131
|
+
} else {
|
|
132
|
+
// When grabbing the action from the element, it will have had the basename
|
|
133
|
+
// prefixed to ensure non-JS scenarios work, so strip it since we'll
|
|
134
|
+
// re-prefix in the router
|
|
135
|
+
let attr = target.getAttribute("action");
|
|
136
|
+
action = attr ? stripBasename(attr, basename) : null;
|
|
137
|
+
}
|
|
138
|
+
|
|
128
139
|
method = options.method || target.getAttribute("method") || defaultMethod;
|
|
129
|
-
action = options.action || target.getAttribute("action") || defaultAction;
|
|
130
140
|
encType = options.encType || target.getAttribute("enctype") || defaultEncType;
|
|
131
141
|
formData = new FormData(target);
|
|
132
142
|
|
|
@@ -141,8 +151,17 @@ function getFormSubmissionInfo(target, defaultAction, options) {
|
|
|
141
151
|
} // <button>/<input type="submit"> may override attributes of <form>
|
|
142
152
|
|
|
143
153
|
|
|
154
|
+
if (options.action) {
|
|
155
|
+
action = options.action;
|
|
156
|
+
} else {
|
|
157
|
+
// When grabbing the action from the element, it will have had the basename
|
|
158
|
+
// prefixed to ensure non-JS scenarios work, so strip it since we'll
|
|
159
|
+
// re-prefix in the router
|
|
160
|
+
let attr = target.getAttribute("formaction") || form.getAttribute("action");
|
|
161
|
+
action = attr ? stripBasename(attr, basename) : null;
|
|
162
|
+
}
|
|
163
|
+
|
|
144
164
|
method = options.method || target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod;
|
|
145
|
-
action = options.action || target.getAttribute("formaction") || form.getAttribute("action") || defaultAction;
|
|
146
165
|
encType = options.encType || target.getAttribute("formenctype") || form.getAttribute("enctype") || defaultEncType;
|
|
147
166
|
formData = new FormData(form); // Include name + value from a <button>, appending in case the button name
|
|
148
167
|
// matches an existing input name
|
|
@@ -154,7 +173,7 @@ function getFormSubmissionInfo(target, defaultAction, options) {
|
|
|
154
173
|
throw new Error("Cannot submit element that is not <form>, <button>, or " + "<input type=\"submit|image\">");
|
|
155
174
|
} else {
|
|
156
175
|
method = options.method || defaultMethod;
|
|
157
|
-
action = options.action ||
|
|
176
|
+
action = options.action || null;
|
|
158
177
|
encType = options.encType || defaultEncType;
|
|
159
178
|
|
|
160
179
|
if (target instanceof FormData) {
|
|
@@ -174,13 +193,8 @@ function getFormSubmissionInfo(target, defaultAction, options) {
|
|
|
174
193
|
}
|
|
175
194
|
}
|
|
176
195
|
|
|
177
|
-
let {
|
|
178
|
-
protocol,
|
|
179
|
-
host
|
|
180
|
-
} = window.location;
|
|
181
|
-
let url = new URL(action, protocol + "//" + host);
|
|
182
196
|
return {
|
|
183
|
-
|
|
197
|
+
action,
|
|
184
198
|
method: method.toLowerCase(),
|
|
185
199
|
encType,
|
|
186
200
|
formData
|
|
@@ -193,25 +207,29 @@ const _excluded = ["onClick", "relative", "reloadDocument", "replace", "state",
|
|
|
193
207
|
function createBrowserRouter(routes, opts) {
|
|
194
208
|
return createRouter({
|
|
195
209
|
basename: opts == null ? void 0 : opts.basename,
|
|
196
|
-
future: opts == null ? void 0 : opts.future,
|
|
210
|
+
future: _extends({}, opts == null ? void 0 : opts.future, {
|
|
211
|
+
v7_prependBasename: true
|
|
212
|
+
}),
|
|
197
213
|
history: createBrowserHistory({
|
|
198
214
|
window: opts == null ? void 0 : opts.window
|
|
199
215
|
}),
|
|
200
216
|
hydrationData: (opts == null ? void 0 : opts.hydrationData) || parseHydrationData(),
|
|
201
217
|
routes,
|
|
202
|
-
|
|
218
|
+
mapRouteProperties: UNSAFE_mapRouteProperties
|
|
203
219
|
}).initialize();
|
|
204
220
|
}
|
|
205
221
|
function createHashRouter(routes, opts) {
|
|
206
222
|
return createRouter({
|
|
207
223
|
basename: opts == null ? void 0 : opts.basename,
|
|
208
|
-
future: opts == null ? void 0 : opts.future,
|
|
224
|
+
future: _extends({}, opts == null ? void 0 : opts.future, {
|
|
225
|
+
v7_prependBasename: true
|
|
226
|
+
}),
|
|
209
227
|
history: createHashHistory({
|
|
210
228
|
window: opts == null ? void 0 : opts.window
|
|
211
229
|
}),
|
|
212
230
|
hydrationData: (opts == null ? void 0 : opts.hydrationData) || parseHydrationData(),
|
|
213
231
|
routes,
|
|
214
|
-
|
|
232
|
+
mapRouteProperties: UNSAFE_mapRouteProperties
|
|
215
233
|
}).initialize();
|
|
216
234
|
}
|
|
217
235
|
|
|
@@ -381,15 +399,20 @@ const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref4, ref) {
|
|
|
381
399
|
absoluteHref = to; // Only check for external origins client-side
|
|
382
400
|
|
|
383
401
|
if (isBrowser) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
402
|
+
try {
|
|
403
|
+
let currentUrl = new URL(window.location.href);
|
|
404
|
+
let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to);
|
|
405
|
+
let path = stripBasename(targetUrl.pathname, basename);
|
|
406
|
+
|
|
407
|
+
if (targetUrl.origin === currentUrl.origin && path != null) {
|
|
408
|
+
// Strip the protocol/origin/basename for same-origin absolute URLs
|
|
409
|
+
to = path + targetUrl.search + targetUrl.hash;
|
|
410
|
+
} else {
|
|
411
|
+
isExternal = true;
|
|
412
|
+
}
|
|
413
|
+
} catch (e) {
|
|
414
|
+
// We can't do external URL detection without a valid URL
|
|
415
|
+
process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, "<Link to=\"" + to + "\"> contains an invalid URL which will probably break " + "when clicked - please update to a valid URL path.") : void 0;
|
|
393
416
|
}
|
|
394
417
|
}
|
|
395
418
|
} // Rendered into <a href> for relative URLs
|
|
@@ -687,11 +710,14 @@ function useSubmit() {
|
|
|
687
710
|
return useSubmitImpl();
|
|
688
711
|
}
|
|
689
712
|
|
|
690
|
-
function useSubmitImpl(fetcherKey,
|
|
713
|
+
function useSubmitImpl(fetcherKey, fetcherRouteId) {
|
|
691
714
|
let {
|
|
692
715
|
router
|
|
693
716
|
} = useDataRouterContext(DataRouterHook.UseSubmitImpl);
|
|
694
|
-
let
|
|
717
|
+
let {
|
|
718
|
+
basename
|
|
719
|
+
} = React.useContext(UNSAFE_NavigationContext);
|
|
720
|
+
let currentRouteId = UNSAFE_useRouteId();
|
|
695
721
|
return React.useCallback(function (target, options) {
|
|
696
722
|
if (options === void 0) {
|
|
697
723
|
options = {};
|
|
@@ -702,14 +728,13 @@ function useSubmitImpl(fetcherKey, routeId) {
|
|
|
702
728
|
}
|
|
703
729
|
|
|
704
730
|
let {
|
|
731
|
+
action,
|
|
705
732
|
method,
|
|
706
733
|
encType,
|
|
707
|
-
formData
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
let href = url.pathname + url.search;
|
|
734
|
+
formData
|
|
735
|
+
} = getFormSubmissionInfo(target, options, basename); // Base options shared between fetch() and navigate()
|
|
736
|
+
|
|
711
737
|
let opts = {
|
|
712
|
-
replace: options.replace,
|
|
713
738
|
preventScrollReset: options.preventScrollReset,
|
|
714
739
|
formData,
|
|
715
740
|
formMethod: method,
|
|
@@ -717,13 +742,18 @@ function useSubmitImpl(fetcherKey, routeId) {
|
|
|
717
742
|
};
|
|
718
743
|
|
|
719
744
|
if (fetcherKey) {
|
|
720
|
-
!(
|
|
721
|
-
router.fetch(fetcherKey,
|
|
745
|
+
!(fetcherRouteId != null) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "No routeId available for useFetcher()") : UNSAFE_invariant(false) : void 0;
|
|
746
|
+
router.fetch(fetcherKey, fetcherRouteId, action, opts);
|
|
722
747
|
} else {
|
|
723
|
-
router.navigate(
|
|
748
|
+
router.navigate(action, _extends({}, opts, {
|
|
749
|
+
replace: options.replace,
|
|
750
|
+
fromRouteId: currentRouteId
|
|
751
|
+
}));
|
|
724
752
|
}
|
|
725
|
-
}, [
|
|
726
|
-
}
|
|
753
|
+
}, [router, basename, fetcherKey, fetcherRouteId, currentRouteId]);
|
|
754
|
+
} // v7: Eventually we should deprecate this entirely in favor of using the
|
|
755
|
+
// router method directly?
|
|
756
|
+
|
|
727
757
|
|
|
728
758
|
function useFormAction(action, _temp2) {
|
|
729
759
|
let {
|
|
@@ -834,7 +864,7 @@ function useFetcher() {
|
|
|
834
864
|
// fetcher is no longer around.
|
|
835
865
|
return () => {
|
|
836
866
|
if (!router) {
|
|
837
|
-
console.warn("No
|
|
867
|
+
console.warn("No router available to clean up from useFetcher()");
|
|
838
868
|
return;
|
|
839
869
|
}
|
|
840
870
|
|