react-router-dom 6.17.0 → 6.18.0-pre.0
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 +21 -0
- package/dist/dom.d.ts +8 -0
- package/dist/index.d.ts +24 -6
- package/dist/index.js +156 -108
- package/dist/index.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/react-router-dom.development.js +157 -103
- 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.js +7 -1
- package/dist/server.mjs +8 -2
- package/dist/umd/react-router-dom.development.js +163 -108
- 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.js +7 -1
- package/server.mjs +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# `react-router-dom`
|
|
2
2
|
|
|
3
|
+
## 6.18.0-pre.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add support for manual fetcher key specification via `useFetcher({ key: string })` so you can access the same fetcher instance from different components in your application without prop-drilling ([RFC](https://github.com/remix-run/remix/discussions/7698)) ([#10960](https://github.com/remix-run/react-router/pull/10960))
|
|
8
|
+
|
|
9
|
+
- Fetcher keys are now also exposed on the fetchers returned from `useFetchers` so that they can be looked up by `key`
|
|
10
|
+
|
|
11
|
+
- Add `navigate`/`fetcherKey` params/props to `useSumbit`/`Form` to support kicking off a fetcher submission under the hood with an optionally user-specified `key` ([#10960](https://github.com/remix-run/react-router/pull/10960))
|
|
12
|
+
|
|
13
|
+
- Invoking a fetcher in this way is ephemeral and stateless
|
|
14
|
+
- If you need to access the state of one of these fetchers, you will need to leverage `useFetcher({ key })` to look it up elsewhere
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Adds a fetcher context to `RouterProvider` that holds completed fetcher data, in preparation for the upcoming future flag that will change the fetcher persistence/cleanup behavior ([#10961](https://github.com/remix-run/react-router/pull/10961))
|
|
19
|
+
- Fix the `future`prop on `BrowserRouter`, `HashRouter` and `MemoryRouter` so that it accepts a `Partial<FutureConfig>` instead of requiring all flags to be included. ([#10962](https://github.com/remix-run/react-router/pull/10962))
|
|
20
|
+
- Updated dependencies:
|
|
21
|
+
- `@remix-run/router@1.11.0-pre.0`
|
|
22
|
+
- `react-router@6.18.0-pre.0`
|
|
23
|
+
|
|
3
24
|
## 6.17.0
|
|
4
25
|
|
|
5
26
|
### Minor Changes
|
package/dist/dom.d.ts
CHANGED
|
@@ -56,6 +56,14 @@ export interface SubmitOptions {
|
|
|
56
56
|
* Defaults to "application/x-www-form-urlencoded".
|
|
57
57
|
*/
|
|
58
58
|
encType?: FormEncType;
|
|
59
|
+
/**
|
|
60
|
+
* Indicate a specific fetcherKey to use when using navigate=false
|
|
61
|
+
*/
|
|
62
|
+
fetcherKey?: string;
|
|
63
|
+
/**
|
|
64
|
+
* navigate=false will use a fetcher instead of a navigation
|
|
65
|
+
*/
|
|
66
|
+
navigate?: boolean;
|
|
59
67
|
/**
|
|
60
68
|
* Set `true` to replace the current entry in the browser's history stack
|
|
61
69
|
* instead of creating a new one (i.e. stay on "the same page"). Defaults
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,13 @@ type ViewTransitionContextObject = {
|
|
|
36
36
|
};
|
|
37
37
|
declare const ViewTransitionContext: React.Context<ViewTransitionContextObject>;
|
|
38
38
|
export { ViewTransitionContext as UNSAFE_ViewTransitionContext };
|
|
39
|
+
type FetchersContextObject = {
|
|
40
|
+
fetcherData: Map<string, any>;
|
|
41
|
+
register: (key: string) => void;
|
|
42
|
+
unregister: (key: string) => void;
|
|
43
|
+
};
|
|
44
|
+
declare const FetchersContext: React.Context<FetchersContextObject | null>;
|
|
45
|
+
export { FetchersContext as UNSAFE_FetchersContext };
|
|
39
46
|
interface ViewTransition {
|
|
40
47
|
finished: Promise<void>;
|
|
41
48
|
ready: Promise<void>;
|
|
@@ -49,7 +56,7 @@ export declare function RouterProvider({ fallbackElement, router, future, }: Rou
|
|
|
49
56
|
export interface BrowserRouterProps {
|
|
50
57
|
basename?: string;
|
|
51
58
|
children?: React.ReactNode;
|
|
52
|
-
future?: FutureConfig
|
|
59
|
+
future?: Partial<FutureConfig>;
|
|
53
60
|
window?: Window;
|
|
54
61
|
}
|
|
55
62
|
/**
|
|
@@ -59,7 +66,7 @@ export declare function BrowserRouter({ basename, children, future, window, }: B
|
|
|
59
66
|
export interface HashRouterProps {
|
|
60
67
|
basename?: string;
|
|
61
68
|
children?: React.ReactNode;
|
|
62
|
-
future?: FutureConfig
|
|
69
|
+
future?: Partial<FutureConfig>;
|
|
63
70
|
window?: Window;
|
|
64
71
|
}
|
|
65
72
|
/**
|
|
@@ -147,6 +154,14 @@ export interface FetcherFormProps extends React.FormHTMLAttributes<HTMLFormEleme
|
|
|
147
154
|
onSubmit?: React.FormEventHandler<HTMLFormElement>;
|
|
148
155
|
}
|
|
149
156
|
export interface FormProps extends FetcherFormProps {
|
|
157
|
+
/**
|
|
158
|
+
* Indicate a specific fetcherKey to use when using navigate=false
|
|
159
|
+
*/
|
|
160
|
+
fetcherKey?: string;
|
|
161
|
+
/**
|
|
162
|
+
* navigate=false will use a fetcher instead of a navigation
|
|
163
|
+
*/
|
|
164
|
+
navigate?: boolean;
|
|
150
165
|
/**
|
|
151
166
|
* Forces a full document navigation instead of a fetch.
|
|
152
167
|
*/
|
|
@@ -238,9 +253,8 @@ export declare function useSubmit(): SubmitFunction;
|
|
|
238
253
|
export declare function useFormAction(action?: string, { relative }?: {
|
|
239
254
|
relative?: RelativeRoutingType;
|
|
240
255
|
}): string;
|
|
241
|
-
declare function createFetcherForm(fetcherKey: string, routeId: string): React.ForwardRefExoticComponent<FetcherFormProps & React.RefAttributes<HTMLFormElement>>;
|
|
242
256
|
export type FetcherWithComponents<TData> = Fetcher<TData> & {
|
|
243
|
-
Form:
|
|
257
|
+
Form: React.ForwardRefExoticComponent<FetcherFormProps & React.RefAttributes<HTMLFormElement>>;
|
|
244
258
|
submit: FetcherSubmitFunction;
|
|
245
259
|
load: (href: string) => void;
|
|
246
260
|
};
|
|
@@ -248,12 +262,16 @@ export type FetcherWithComponents<TData> = Fetcher<TData> & {
|
|
|
248
262
|
* Interacts with route loaders and actions without causing a navigation. Great
|
|
249
263
|
* for any interaction that stays on the same page.
|
|
250
264
|
*/
|
|
251
|
-
export declare function useFetcher<TData = any>(
|
|
265
|
+
export declare function useFetcher<TData = any>({ key, }?: {
|
|
266
|
+
key?: string;
|
|
267
|
+
}): FetcherWithComponents<TData>;
|
|
252
268
|
/**
|
|
253
269
|
* Provides all fetchers currently on the page. Useful for layouts and parent
|
|
254
270
|
* routes that need to provide pending/optimistic UI regarding the fetch.
|
|
255
271
|
*/
|
|
256
|
-
export declare function useFetchers(): Fetcher
|
|
272
|
+
export declare function useFetchers(): (Fetcher & {
|
|
273
|
+
key: string;
|
|
274
|
+
})[];
|
|
257
275
|
/**
|
|
258
276
|
* When rendered inside a RouterProvider, will restore scroll positions on navigations
|
|
259
277
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React Router DOM v6.
|
|
2
|
+
* React Router DOM v6.18.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import * as React from 'react';
|
|
12
12
|
import { UNSAFE_mapRouteProperties, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, Router, UNSAFE_useRoutesImpl, UNSAFE_NavigationContext, useHref, useResolvedPath, useLocation, useNavigate, createPath, UNSAFE_useRouteId, UNSAFE_RouteContext, useMatches, useNavigation, unstable_useBlocker } from 'react-router';
|
|
13
13
|
export { AbortedDeferredError, Await, MemoryRouter, Navigate, NavigationType, Outlet, Route, Router, 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, redirectDocument, 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, UNSAFE_warning, createRouter, createBrowserHistory, createHashHistory, UNSAFE_ErrorResponseImpl, UNSAFE_invariant, joinPaths, matchPath } from '@remix-run/router';
|
|
14
|
+
import { stripBasename, UNSAFE_warning, createRouter, createBrowserHistory, createHashHistory, UNSAFE_ErrorResponseImpl, UNSAFE_invariant, joinPaths, IDLE_FETCHER, matchPath } from '@remix-run/router';
|
|
15
15
|
|
|
16
16
|
function _extends() {
|
|
17
17
|
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
@@ -208,7 +208,7 @@ function getFormSubmissionInfo(target, basename) {
|
|
|
208
208
|
|
|
209
209
|
const _excluded = ["onClick", "relative", "reloadDocument", "replace", "state", "target", "to", "preventScrollReset", "unstable_viewTransition"],
|
|
210
210
|
_excluded2 = ["aria-current", "caseSensitive", "className", "end", "style", "to", "unstable_viewTransition", "children"],
|
|
211
|
-
_excluded3 = ["reloadDocument", "replace", "state", "method", "action", "onSubmit", "
|
|
211
|
+
_excluded3 = ["fetcherKey", "navigate", "reloadDocument", "replace", "state", "method", "action", "onSubmit", "relative", "preventScrollReset", "unstable_viewTransition"];
|
|
212
212
|
function createBrowserRouter(routes, opts) {
|
|
213
213
|
return createRouter({
|
|
214
214
|
basename: opts == null ? void 0 : opts.basename,
|
|
@@ -294,6 +294,10 @@ const ViewTransitionContext = /*#__PURE__*/React.createContext({
|
|
|
294
294
|
if (process.env.NODE_ENV !== "production") {
|
|
295
295
|
ViewTransitionContext.displayName = "ViewTransition";
|
|
296
296
|
}
|
|
297
|
+
const FetchersContext = /*#__PURE__*/React.createContext(null);
|
|
298
|
+
if (process.env.NODE_ENV !== "production") {
|
|
299
|
+
FetchersContext.displayName = "Fetchers";
|
|
300
|
+
}
|
|
297
301
|
//#endregion
|
|
298
302
|
////////////////////////////////////////////////////////////////////////////////
|
|
299
303
|
//#region Components
|
|
@@ -356,6 +360,10 @@ function RouterProvider(_ref) {
|
|
|
356
360
|
router,
|
|
357
361
|
future
|
|
358
362
|
} = _ref;
|
|
363
|
+
let {
|
|
364
|
+
fetcherContext,
|
|
365
|
+
fetcherData
|
|
366
|
+
} = useFetcherDataLayer();
|
|
359
367
|
let [state, setStateImpl] = React.useState(router.state);
|
|
360
368
|
let [pendingState, setPendingState] = React.useState();
|
|
361
369
|
let [vtContext, setVtContext] = React.useState({
|
|
@@ -378,6 +386,11 @@ function RouterProvider(_ref) {
|
|
|
378
386
|
let {
|
|
379
387
|
unstable_viewTransitionOpts: viewTransitionOpts
|
|
380
388
|
} = _ref2;
|
|
389
|
+
newState.fetchers.forEach((fetcher, key) => {
|
|
390
|
+
if (fetcher.data !== undefined) {
|
|
391
|
+
fetcherData.current.set(key, fetcher.data);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
381
394
|
if (!viewTransitionOpts || router.window == null || typeof router.window.document.startViewTransition !== "function") {
|
|
382
395
|
// Mid-navigation state update, or startViewTransition isn't available
|
|
383
396
|
optInStartTransition(() => setStateImpl(newState));
|
|
@@ -400,7 +413,7 @@ function RouterProvider(_ref) {
|
|
|
400
413
|
nextLocation: viewTransitionOpts.nextLocation
|
|
401
414
|
});
|
|
402
415
|
}
|
|
403
|
-
}, [
|
|
416
|
+
}, [router.window, transition, renderDfd, fetcherData, optInStartTransition]);
|
|
404
417
|
// Need to use a layout effect here so we are subscribed early enough to
|
|
405
418
|
// pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
|
|
406
419
|
React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
|
|
@@ -486,6 +499,8 @@ function RouterProvider(_ref) {
|
|
|
486
499
|
value: dataRouterContext
|
|
487
500
|
}, /*#__PURE__*/React.createElement(UNSAFE_DataRouterStateContext.Provider, {
|
|
488
501
|
value: state
|
|
502
|
+
}, /*#__PURE__*/React.createElement(FetchersContext.Provider, {
|
|
503
|
+
value: fetcherContext
|
|
489
504
|
}, /*#__PURE__*/React.createElement(ViewTransitionContext.Provider, {
|
|
490
505
|
value: vtContext
|
|
491
506
|
}, /*#__PURE__*/React.createElement(Router, {
|
|
@@ -496,7 +511,7 @@ function RouterProvider(_ref) {
|
|
|
496
511
|
}, state.initialized ? /*#__PURE__*/React.createElement(DataRoutes, {
|
|
497
512
|
routes: router.routes,
|
|
498
513
|
state: state
|
|
499
|
-
}) : fallbackElement)))), null);
|
|
514
|
+
}) : fallbackElement))))), null);
|
|
500
515
|
}
|
|
501
516
|
function DataRoutes(_ref3) {
|
|
502
517
|
let {
|
|
@@ -765,34 +780,26 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
765
780
|
* requests, allowing components to add nicer UX to the page as the form is
|
|
766
781
|
* submitted and returns with data.
|
|
767
782
|
*/
|
|
768
|
-
const Form = /*#__PURE__*/React.forwardRef((
|
|
769
|
-
let submit = useSubmit();
|
|
770
|
-
return /*#__PURE__*/React.createElement(FormImpl, _extends({}, props, {
|
|
771
|
-
submit: submit,
|
|
772
|
-
ref: ref
|
|
773
|
-
}));
|
|
774
|
-
});
|
|
775
|
-
if (process.env.NODE_ENV !== "production") {
|
|
776
|
-
Form.displayName = "Form";
|
|
777
|
-
}
|
|
778
|
-
const FormImpl = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
783
|
+
const Form = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
779
784
|
let {
|
|
785
|
+
fetcherKey,
|
|
786
|
+
navigate,
|
|
780
787
|
reloadDocument,
|
|
781
788
|
replace,
|
|
782
789
|
state,
|
|
783
790
|
method = defaultMethod,
|
|
784
791
|
action,
|
|
785
792
|
onSubmit,
|
|
786
|
-
submit,
|
|
787
793
|
relative,
|
|
788
794
|
preventScrollReset,
|
|
789
795
|
unstable_viewTransition
|
|
790
796
|
} = _ref9,
|
|
791
797
|
props = _objectWithoutPropertiesLoose(_ref9, _excluded3);
|
|
792
|
-
let
|
|
798
|
+
let submit = useSubmit();
|
|
793
799
|
let formAction = useFormAction(action, {
|
|
794
800
|
relative
|
|
795
801
|
});
|
|
802
|
+
let formMethod = method.toLowerCase() === "get" ? "get" : "post";
|
|
796
803
|
let submitHandler = event => {
|
|
797
804
|
onSubmit && onSubmit(event);
|
|
798
805
|
if (event.defaultPrevented) return;
|
|
@@ -800,7 +807,9 @@ const FormImpl = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
|
800
807
|
let submitter = event.nativeEvent.submitter;
|
|
801
808
|
let submitMethod = (submitter == null ? void 0 : submitter.getAttribute("formmethod")) || method;
|
|
802
809
|
submit(submitter || event.currentTarget, {
|
|
810
|
+
fetcherKey,
|
|
803
811
|
method: submitMethod,
|
|
812
|
+
navigate,
|
|
804
813
|
replace,
|
|
805
814
|
state,
|
|
806
815
|
relative,
|
|
@@ -816,7 +825,7 @@ const FormImpl = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
|
816
825
|
}, props));
|
|
817
826
|
});
|
|
818
827
|
if (process.env.NODE_ENV !== "production") {
|
|
819
|
-
|
|
828
|
+
Form.displayName = "Form";
|
|
820
829
|
}
|
|
821
830
|
/**
|
|
822
831
|
* This component will emulate the browser's scroll restoration on location
|
|
@@ -850,9 +859,11 @@ var DataRouterHook;
|
|
|
850
859
|
})(DataRouterHook || (DataRouterHook = {}));
|
|
851
860
|
var DataRouterStateHook;
|
|
852
861
|
(function (DataRouterStateHook) {
|
|
862
|
+
DataRouterStateHook["UseFetcher"] = "useFetcher";
|
|
853
863
|
DataRouterStateHook["UseFetchers"] = "useFetchers";
|
|
854
864
|
DataRouterStateHook["UseScrollRestoration"] = "useScrollRestoration";
|
|
855
865
|
})(DataRouterStateHook || (DataRouterStateHook = {}));
|
|
866
|
+
// Internal hooks
|
|
856
867
|
function getDataRouterConsoleError(hookName) {
|
|
857
868
|
return hookName + " must be used within a data router. See https://reactrouter.com/routers/picking-a-router.";
|
|
858
869
|
}
|
|
@@ -866,6 +877,37 @@ function useDataRouterState(hookName) {
|
|
|
866
877
|
!state ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
|
|
867
878
|
return state;
|
|
868
879
|
}
|
|
880
|
+
function useFetcherDataLayer() {
|
|
881
|
+
let fetcherRefs = React.useRef(new Map());
|
|
882
|
+
let fetcherData = React.useRef(new Map());
|
|
883
|
+
let registerFetcher = React.useCallback(key => {
|
|
884
|
+
let count = fetcherRefs.current.get(key);
|
|
885
|
+
if (count == null) {
|
|
886
|
+
fetcherRefs.current.set(key, 1);
|
|
887
|
+
} else {
|
|
888
|
+
fetcherRefs.current.set(key, count + 1);
|
|
889
|
+
}
|
|
890
|
+
}, [fetcherRefs]);
|
|
891
|
+
let unregisterFetcher = React.useCallback(key => {
|
|
892
|
+
let count = fetcherRefs.current.get(key);
|
|
893
|
+
if (count == null || count <= 1) {
|
|
894
|
+
fetcherRefs.current.delete(key);
|
|
895
|
+
fetcherData.current.delete(key);
|
|
896
|
+
} else {
|
|
897
|
+
fetcherRefs.current.set(key, count - 1);
|
|
898
|
+
}
|
|
899
|
+
}, [fetcherData, fetcherRefs]);
|
|
900
|
+
let fetcherContext = React.useMemo(() => ({
|
|
901
|
+
fetcherData: fetcherData.current,
|
|
902
|
+
register: registerFetcher,
|
|
903
|
+
unregister: unregisterFetcher
|
|
904
|
+
}), [fetcherData, registerFetcher, unregisterFetcher]);
|
|
905
|
+
return {
|
|
906
|
+
fetcherContext,
|
|
907
|
+
fetcherData
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
// External hooks
|
|
869
911
|
/**
|
|
870
912
|
* Handles the click behavior for router `<Link>` components. This is useful if
|
|
871
913
|
* you need to create custom `<Link>` components with the same click behavior we
|
|
@@ -928,6 +970,8 @@ function validateClientSideSubmission() {
|
|
|
928
970
|
throw new Error("You are calling submit during the server render. " + "Try calling submit within a `useEffect` or callback instead.");
|
|
929
971
|
}
|
|
930
972
|
}
|
|
973
|
+
let fetcherId = 0;
|
|
974
|
+
let getUniqueFetcherId = () => "__" + String(++fetcherId) + "__";
|
|
931
975
|
/**
|
|
932
976
|
* Returns a function that may be used to programmatically submit a form (or
|
|
933
977
|
* some arbitrary data) to the server.
|
|
@@ -952,50 +996,29 @@ function useSubmit() {
|
|
|
952
996
|
formData,
|
|
953
997
|
body
|
|
954
998
|
} = getFormSubmissionInfo(target, basename);
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
basename
|
|
977
|
-
} = React.useContext(UNSAFE_NavigationContext);
|
|
978
|
-
return React.useCallback(function (target, options) {
|
|
979
|
-
if (options === void 0) {
|
|
980
|
-
options = {};
|
|
999
|
+
if (options.navigate === false) {
|
|
1000
|
+
let key = options.fetcherKey || getUniqueFetcherId();
|
|
1001
|
+
router.fetch(key, currentRouteId, options.action || action, {
|
|
1002
|
+
preventScrollReset: options.preventScrollReset,
|
|
1003
|
+
formData,
|
|
1004
|
+
body,
|
|
1005
|
+
formMethod: options.method || method,
|
|
1006
|
+
formEncType: options.encType || encType
|
|
1007
|
+
});
|
|
1008
|
+
} else {
|
|
1009
|
+
router.navigate(options.action || action, {
|
|
1010
|
+
preventScrollReset: options.preventScrollReset,
|
|
1011
|
+
formData,
|
|
1012
|
+
body,
|
|
1013
|
+
formMethod: options.method || method,
|
|
1014
|
+
formEncType: options.encType || encType,
|
|
1015
|
+
replace: options.replace,
|
|
1016
|
+
state: options.state,
|
|
1017
|
+
fromRouteId: currentRouteId,
|
|
1018
|
+
unstable_viewTransition: options.unstable_viewTransition
|
|
1019
|
+
});
|
|
981
1020
|
}
|
|
982
|
-
|
|
983
|
-
let {
|
|
984
|
-
action,
|
|
985
|
-
method,
|
|
986
|
-
encType,
|
|
987
|
-
formData,
|
|
988
|
-
body
|
|
989
|
-
} = getFormSubmissionInfo(target, basename);
|
|
990
|
-
!(fetcherRouteId != null) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "No routeId available for useFetcher()") : UNSAFE_invariant(false) : void 0;
|
|
991
|
-
router.fetch(fetcherKey, fetcherRouteId, options.action || action, {
|
|
992
|
-
preventScrollReset: options.preventScrollReset,
|
|
993
|
-
formData,
|
|
994
|
-
body,
|
|
995
|
-
formMethod: options.method || method,
|
|
996
|
-
formEncType: options.encType || encType
|
|
997
|
-
});
|
|
998
|
-
}, [router, basename, fetcherKey, fetcherRouteId]);
|
|
1021
|
+
}, [router, basename, currentRouteId]);
|
|
999
1022
|
}
|
|
1000
1023
|
// v7: Eventually we should deprecate this entirely in favor of using the
|
|
1001
1024
|
// router method directly?
|
|
@@ -1045,63 +1068,83 @@ function useFormAction(action, _temp2) {
|
|
|
1045
1068
|
}
|
|
1046
1069
|
return createPath(path);
|
|
1047
1070
|
}
|
|
1048
|
-
function createFetcherForm(fetcherKey, routeId) {
|
|
1049
|
-
let FetcherForm = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1050
|
-
let submit = useSubmitFetcher(fetcherKey, routeId);
|
|
1051
|
-
return /*#__PURE__*/React.createElement(FormImpl, _extends({}, props, {
|
|
1052
|
-
ref: ref,
|
|
1053
|
-
submit: submit
|
|
1054
|
-
}));
|
|
1055
|
-
});
|
|
1056
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1057
|
-
FetcherForm.displayName = "fetcher.Form";
|
|
1058
|
-
}
|
|
1059
|
-
return FetcherForm;
|
|
1060
|
-
}
|
|
1061
|
-
let fetcherId = 0;
|
|
1062
1071
|
// TODO: (v7) Change the useFetcher generic default from `any` to `unknown`
|
|
1063
1072
|
/**
|
|
1064
1073
|
* Interacts with route loaders and actions without causing a navigation. Great
|
|
1065
1074
|
* for any interaction that stays on the same page.
|
|
1066
1075
|
*/
|
|
1067
|
-
function useFetcher() {
|
|
1076
|
+
function useFetcher(_temp3) {
|
|
1068
1077
|
var _route$matches;
|
|
1078
|
+
let {
|
|
1079
|
+
key
|
|
1080
|
+
} = _temp3 === void 0 ? {} : _temp3;
|
|
1069
1081
|
let {
|
|
1070
1082
|
router
|
|
1071
1083
|
} = useDataRouterContext(DataRouterHook.UseFetcher);
|
|
1084
|
+
let state = useDataRouterState(DataRouterStateHook.UseFetcher);
|
|
1085
|
+
let fetchersContext = React.useContext(FetchersContext);
|
|
1072
1086
|
let route = React.useContext(UNSAFE_RouteContext);
|
|
1073
|
-
!route ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher must be used inside a RouteContext") : UNSAFE_invariant(false) : void 0;
|
|
1074
1087
|
let routeId = (_route$matches = route.matches[route.matches.length - 1]) == null ? void 0 : _route$matches.route.id;
|
|
1088
|
+
!fetchersContext ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher must be used inside a FetchersContext") : UNSAFE_invariant(false) : void 0;
|
|
1089
|
+
!route ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher must be used inside a RouteContext") : UNSAFE_invariant(false) : void 0;
|
|
1075
1090
|
!(routeId != null) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useFetcher can only be used on routes that contain a unique \"id\"") : UNSAFE_invariant(false) : void 0;
|
|
1076
|
-
|
|
1077
|
-
let [
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1091
|
+
// Fetcher key handling
|
|
1092
|
+
let [fetcherKey, setFetcherKey] = React.useState(key || "");
|
|
1093
|
+
if (!fetcherKey) {
|
|
1094
|
+
setFetcherKey(getUniqueFetcherId());
|
|
1095
|
+
}
|
|
1096
|
+
// Registration/cleanup
|
|
1097
|
+
let {
|
|
1098
|
+
fetcherData,
|
|
1099
|
+
register,
|
|
1100
|
+
unregister
|
|
1101
|
+
} = fetchersContext;
|
|
1102
|
+
React.useEffect(() => {
|
|
1103
|
+
register(fetcherKey);
|
|
1104
|
+
return () => {
|
|
1105
|
+
// Unregister from ref counting for the data layer
|
|
1106
|
+
unregister(fetcherKey);
|
|
1107
|
+
// Tell the router we've unmounted - if v7_fetcherPersist is enabled this
|
|
1108
|
+
// will not delete immediately but instead queue up a delete after the
|
|
1109
|
+
// fetcher returns to an `idle` state
|
|
1110
|
+
router.deleteFetcher(fetcherKey);
|
|
1111
|
+
};
|
|
1112
|
+
}, [router, fetcherKey, register, unregister]);
|
|
1113
|
+
// Fetcher additions
|
|
1114
|
+
let load = React.useCallback(href => {
|
|
1083
1115
|
!routeId ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "No routeId available for fetcher.load()") : UNSAFE_invariant(false) : void 0;
|
|
1084
1116
|
router.fetch(fetcherKey, routeId, href);
|
|
1085
|
-
});
|
|
1086
|
-
let
|
|
1087
|
-
let
|
|
1117
|
+
}, [fetcherKey, routeId, router]);
|
|
1118
|
+
let submitImpl = useSubmit();
|
|
1119
|
+
let submit = React.useCallback((target, opts) => {
|
|
1120
|
+
submitImpl(target, _extends({}, opts, {
|
|
1121
|
+
navigate: false,
|
|
1122
|
+
fetcherKey
|
|
1123
|
+
}));
|
|
1124
|
+
}, [fetcherKey, submitImpl]);
|
|
1125
|
+
let FetcherForm = React.useMemo(() => {
|
|
1126
|
+
let FetcherForm = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
1127
|
+
return /*#__PURE__*/React.createElement(Form, _extends({}, props, {
|
|
1128
|
+
navigate: false,
|
|
1129
|
+
fetcherKey: fetcherKey,
|
|
1130
|
+
ref: ref
|
|
1131
|
+
}));
|
|
1132
|
+
});
|
|
1133
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1134
|
+
FetcherForm.displayName = "fetcher.Form";
|
|
1135
|
+
}
|
|
1136
|
+
return FetcherForm;
|
|
1137
|
+
}, [fetcherKey]);
|
|
1138
|
+
// Exposed FetcherWithComponents
|
|
1139
|
+
let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER;
|
|
1140
|
+
let data = fetcherData.get(fetcherKey);
|
|
1088
1141
|
let fetcherWithComponents = React.useMemo(() => _extends({
|
|
1089
|
-
Form,
|
|
1142
|
+
Form: FetcherForm,
|
|
1090
1143
|
submit,
|
|
1091
1144
|
load
|
|
1092
|
-
}, fetcher
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
// twice on mount? We really just need to garbage collect here when this
|
|
1096
|
-
// fetcher is no longer around.
|
|
1097
|
-
return () => {
|
|
1098
|
-
if (!router) {
|
|
1099
|
-
console.warn("No router available to clean up from useFetcher()");
|
|
1100
|
-
return;
|
|
1101
|
-
}
|
|
1102
|
-
router.deleteFetcher(fetcherKey);
|
|
1103
|
-
};
|
|
1104
|
-
}, [router, fetcherKey]);
|
|
1145
|
+
}, fetcher, {
|
|
1146
|
+
data
|
|
1147
|
+
}), [FetcherForm, submit, load, fetcher, data]);
|
|
1105
1148
|
return fetcherWithComponents;
|
|
1106
1149
|
}
|
|
1107
1150
|
/**
|
|
@@ -1110,18 +1153,23 @@ function useFetcher() {
|
|
|
1110
1153
|
*/
|
|
1111
1154
|
function useFetchers() {
|
|
1112
1155
|
let state = useDataRouterState(DataRouterStateHook.UseFetchers);
|
|
1113
|
-
return
|
|
1156
|
+
return Array.from(state.fetchers.entries()).map(_ref11 => {
|
|
1157
|
+
let [key, fetcher] = _ref11;
|
|
1158
|
+
return _extends({}, fetcher, {
|
|
1159
|
+
key
|
|
1160
|
+
});
|
|
1161
|
+
});
|
|
1114
1162
|
}
|
|
1115
1163
|
const SCROLL_RESTORATION_STORAGE_KEY = "react-router-scroll-positions";
|
|
1116
1164
|
let savedScrollPositions = {};
|
|
1117
1165
|
/**
|
|
1118
1166
|
* When rendered inside a RouterProvider, will restore scroll positions on navigations
|
|
1119
1167
|
*/
|
|
1120
|
-
function useScrollRestoration(
|
|
1168
|
+
function useScrollRestoration(_temp4) {
|
|
1121
1169
|
let {
|
|
1122
1170
|
getKey,
|
|
1123
1171
|
storageKey
|
|
1124
|
-
} =
|
|
1172
|
+
} = _temp4 === void 0 ? {} : _temp4;
|
|
1125
1173
|
let {
|
|
1126
1174
|
router
|
|
1127
1175
|
} = useDataRouterContext(DataRouterHook.UseScrollRestoration);
|
|
@@ -1259,11 +1307,11 @@ function usePageHide(callback, options) {
|
|
|
1259
1307
|
* very incorrectly in some cases) across browsers if user click addition
|
|
1260
1308
|
* back/forward navigations while the confirm is open. Use at your own risk.
|
|
1261
1309
|
*/
|
|
1262
|
-
function usePrompt(
|
|
1310
|
+
function usePrompt(_ref12) {
|
|
1263
1311
|
let {
|
|
1264
1312
|
when,
|
|
1265
1313
|
message
|
|
1266
|
-
} =
|
|
1314
|
+
} = _ref12;
|
|
1267
1315
|
let blocker = unstable_useBlocker(when);
|
|
1268
1316
|
React.useEffect(() => {
|
|
1269
1317
|
if (blocker.state === "blocked") {
|
|
@@ -1326,5 +1374,5 @@ function useViewTransitionState(to, opts) {
|
|
|
1326
1374
|
}
|
|
1327
1375
|
//#endregion
|
|
1328
1376
|
|
|
1329
|
-
export { BrowserRouter, Form, HashRouter, Link, NavLink, RouterProvider, ScrollRestoration, ViewTransitionContext as UNSAFE_ViewTransitionContext, useScrollRestoration as UNSAFE_useScrollRestoration, createBrowserRouter, createHashRouter, createSearchParams, HistoryRouter as unstable_HistoryRouter, usePrompt as unstable_usePrompt, useViewTransitionState as unstable_useViewTransitionState, useBeforeUnload, useFetcher, useFetchers, useFormAction, useLinkClickHandler, useSearchParams, useSubmit };
|
|
1377
|
+
export { BrowserRouter, Form, HashRouter, Link, NavLink, RouterProvider, ScrollRestoration, FetchersContext as UNSAFE_FetchersContext, ViewTransitionContext as UNSAFE_ViewTransitionContext, useScrollRestoration as UNSAFE_useScrollRestoration, createBrowserRouter, createHashRouter, createSearchParams, HistoryRouter as unstable_HistoryRouter, usePrompt as unstable_usePrompt, useViewTransitionState as unstable_useViewTransitionState, useBeforeUnload, useFetcher, useFetchers, useFormAction, useLinkClickHandler, useSearchParams, useSubmit };
|
|
1330
1378
|
//# sourceMappingURL=index.js.map
|