Skip to content

Commit 31beaf4

Browse files
committed
Wire up loaders/actions correctly
1 parent 74c251f commit 31beaf4

File tree

5 files changed

+133
-243
lines changed

5 files changed

+133
-243
lines changed

packages/remix-react/components.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,20 +1047,34 @@ export function useTransition(): Transition {
10471047
}
10481048
}
10491049
} else {
1050+
// TODO: How can we detect this?
1051+
let wasNormalRedirect = false;
1052+
if (wasNormalRedirect) {
1053+
let transition: TransitionStates["LoadingRedirect"] = {
1054+
location,
1055+
state,
1056+
submission: undefined,
1057+
type: "normalRedirect",
1058+
};
1059+
return transition;
1060+
}
1061+
10501062
// TODO: How can we detect a fetch action redirect??? Do we need to
10511063
// check useFetchers? Or could we somehow look at location key?
1052-
1053-
let transition: TransitionStates["LoadingRedirect"] = {
1054-
location,
1055-
state,
1056-
submission: undefined,
1057-
type: "normalRedirect",
1058-
};
1059-
return transition;
1064+
let wasFetchActionRedirect = false;
1065+
if (wasFetchActionRedirect) {
1066+
let transition: TransitionStates["LoadingFetchActionRedirect"] = {
1067+
location,
1068+
state,
1069+
submission: undefined,
1070+
type: "fetchActionRedirect",
1071+
};
1072+
return transition;
1073+
}
10601074
}
10611075
}
10621076

1063-
// If all else fails, it's a normal load!
1077+
// If no scenarios above match, then it's a normal load!
10641078
let transition: TransitionStates["Loading"] = {
10651079
location,
10661080
state: "loading",

packages/remix-react/data.ts

Lines changed: 19 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import type { FormMethod as FormMethodRR } from "react-router-dom";
22

3-
import invariant from "./invariant";
4-
import type { Submission } from "./transition";
5-
63
export type AppData = any;
74

85
export type FormMethod = FormMethodRR;
@@ -33,17 +30,28 @@ export function isRedirectResponse(response: any): boolean {
3330
}
3431

3532
export async function fetchData(
36-
url: URL,
33+
request: Request,
3734
routeId: string,
38-
signal: AbortSignal,
39-
submission?: Submission
35+
isAction: boolean
4036
): Promise<Response | Error> {
37+
let url = new URL(request.url);
4138
url.searchParams.set("_data", routeId);
4239

43-
let init: RequestInit = submission
44-
? getActionInit(submission, signal)
45-
: { credentials: "same-origin", signal };
40+
let init: RequestInit | undefined;
41+
42+
// TODO: There's a bug in @remix-run/router here at the moment where the
43+
// loader Request keeps method POST after a submission. Matt has a local
44+
// fix but this does the trick for now. Once the fix is merged to the
45+
// router, we can remove the isAction param and use the method here
46+
// if (request.method !== "GET") {
47+
if (isAction) {
48+
init = {
49+
method: request.method,
50+
body: await request.formData(),
51+
};
52+
}
4653

54+
// TODO: Dropped credentials:"same-origin" since it's the default
4755
let response = await fetch(url.href, init);
4856

4957
if (isErrorResponse(response)) {
@@ -53,47 +61,7 @@ export async function fetchData(
5361
return error;
5462
}
5563

64+
// TODO: Confirm difference between regex extractData JSON detection versus
65+
// @remix-run/router detection
5666
return response;
5767
}
58-
59-
export async function extractData(response: Response): Promise<AppData> {
60-
// This same algorithm is used on the server to interpret load
61-
// results when we render the HTML page.
62-
let contentType = response.headers.get("Content-Type");
63-
64-
if (contentType && /\bapplication\/json\b/.test(contentType)) {
65-
return response.json();
66-
}
67-
68-
return response.text();
69-
}
70-
71-
function getActionInit(
72-
submission: Submission,
73-
signal: AbortSignal
74-
): RequestInit {
75-
let { encType, method, formData } = submission;
76-
77-
let headers = undefined;
78-
let body = formData;
79-
80-
if (encType === "application/x-www-form-urlencoded") {
81-
body = new URLSearchParams();
82-
for (let [key, value] of formData) {
83-
invariant(
84-
typeof value === "string",
85-
`File inputs are not supported with encType "application/x-www-form-urlencoded", please use "multipart/form-data" instead.`
86-
);
87-
body.append(key, value);
88-
}
89-
headers = { "Content-Type": encType };
90-
}
91-
92-
return {
93-
method,
94-
body,
95-
signal,
96-
credentials: "same-origin",
97-
headers,
98-
};
99-
}

packages/remix-react/routeModules.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type { ComponentType } from "react";
2-
import type { DataRouteMatch, Params, Location } from "react-router-dom";
2+
import type {
3+
DataRouteMatch,
4+
Params,
5+
Location,
6+
ShouldRevalidateFunction,
7+
} from "react-router-dom";
38

49
import type { AppData } from "./data";
510
import type { LinkDescriptor } from "./links";
@@ -22,7 +27,7 @@ export interface RouteModule {
2227
| V1_HtmlMetaDescriptor
2328
| V2_MetaFunction
2429
| V2_HtmlMetaDescriptor[];
25-
unstable_shouldReload?: ShouldReloadFunction;
30+
shouldRevalidate?: ShouldRevalidateFunction;
2631
}
2732

2833
/**

0 commit comments

Comments
 (0)