Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates for Remix on RR 6.4 #9664

Merged
merged 29 commits into from Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dc5dddf
Allow uppercase <Form> methods and fix submitted method override
brophdawg11 Dec 1, 2022
e2f0cca
Remove ?? operator and add lint rules
brophdawg11 Dec 1, 2022
3fce264
Add Error serialization
brophdawg11 Dec 1, 2022
cdbaa27
Mark loader-less routes with null loaderData during SSR
brophdawg11 Dec 1, 2022
e5d0803
Support fetch action redirects in useTransition
brophdawg11 Dec 2, 2022
c9e6851
Merge branch 'dev' into brophdawg11/remix-updates
brophdawg11 Dec 7, 2022
34ee733
Add _isRedirect state for useTransition back compat
brophdawg11 Dec 8, 2022
f188645
Updates for fetcher type and redirect replace logic
brophdawg11 Dec 8, 2022
e8d5340
Add tests for SSR null loader values on non-executed loaders
brophdawg11 Dec 9, 2022
99993d9
more tests for submission replace/push logic
brophdawg11 Dec 9, 2022
e3b31d0
fix test for null loader data during ssr
brophdawg11 Dec 9, 2022
470082b
SSr error serialization tests
brophdawg11 Dec 9, 2022
239bc7c
form tests
brophdawg11 Dec 9, 2022
13a0b4f
Merge branch 'dev' into brophdawg11/remix-updates
brophdawg11 Dec 12, 2022
ecbca64
bundle bump
brophdawg11 Dec 12, 2022
09209b6
Updates to ScrollRestoration for Remix
brophdawg11 Dec 12, 2022
a5e45d7
Export useBeforeUnload
brophdawg11 Dec 12, 2022
6c69af5
Avoid SSR layout effects
brophdawg11 Dec 12, 2022
9c3548f
Add changesets
brophdawg11 Dec 13, 2022
80a50b1
Merge branch 'dev' into brophdawg11/remix-updates
brophdawg11 Dec 13, 2022
6239420
Bundle bump
brophdawg11 Dec 14, 2022
4066857
Remove skip param
brophdawg11 Dec 15, 2022
8ab846b
Update chreck for json content type
brophdawg11 Dec 15, 2022
bb40a35
Revert "more tests for submission replace/push logic"
brophdawg11 Dec 15, 2022
71d7b2f
Revert "Updates for fetcher type and redirect replace logic"
brophdawg11 Dec 15, 2022
2da3b2c
Add _hasFetcherdoneAnything for Remix back-compat
brophdawg11 Dec 15, 2022
c3642e0
Remove changeset for redirect logic in new PR
brophdawg11 Dec 15, 2022
86699a1
Fix tests
brophdawg11 Dec 15, 2022
10b6c5b
Add changeset
brophdawg11 Dec 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/react-router-dom/.eslintrc
Expand Up @@ -7,6 +7,7 @@
"__DEV__": true
},
"rules": {
"strict": 0
"strict": 0,
"no-restricted-syntax": ["error", "LogicalExpression[operator='??']"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See ?? removal below - added a lint rule to prevent that showing up again

}
}
2 changes: 1 addition & 1 deletion packages/react-router-dom/dom.ts
Expand Up @@ -245,5 +245,5 @@ export function getFormSubmissionInfo(
let { protocol, host } = window.location;
let url = new URL(action, `${protocol}//${host}`);

return { url, method, encType, formData };
return { url, method: method.toLowerCase(), encType, formData };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lowercase incoming methods, since <Form method="POST"> is valid HTML

}
16 changes: 13 additions & 3 deletions packages/react-router-dom/index.tsx
Expand Up @@ -252,6 +252,10 @@ function deserializeErrors(
val.data,
val.internal === true
);
} else if (val && val.__type === "Error") {
let error = new Error(val.message);
error.stack = val.stack;
serialized[key] = error;
} else {
serialized[key] = val;
}
Expand Down Expand Up @@ -650,7 +654,14 @@ const FormImpl = React.forwardRef<HTMLFormElement, FormImplProps>(
let submitter = (event as unknown as HTMLSubmitEvent).nativeEvent
.submitter as HTMLFormSubmitter | null;

submit(submitter || event.currentTarget, { method, replace, relative });
let submitMethod =
(submitter?.formMethod as FormMethod | undefined) || method;

submit(submitter || event.currentTarget, {
method: submitMethod,
replace,
relative,
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same fix Remix used to ensure we allow <button type="submit" formmethod="post"> type overrides

};

return (
Expand Down Expand Up @@ -916,10 +927,9 @@ export function useFormAction(
invariant(routeContext, "useFormAction must be used inside a RouteContext");

let [match] = routeContext.matches.slice(-1);
let resolvedAction = action ?? ".";
// Shallow clone path so we can modify it below, otherwise we modify the
// object referenced by useMemo inside useResolvedPath
let path = { ...useResolvedPath(resolvedAction, { relative }) };
let path = { ...useResolvedPath(action ? action : ".", { relative }) };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove ?? usage which breaks older browsers


// Previously we set the default action to ".". The problem with this is that
// `useResolvedPath(".")` excludes search params and the hash of the resolved
Expand Down
6 changes: 6 additions & 0 deletions packages/react-router-dom/server.tsx
Expand Up @@ -157,6 +157,12 @@ function serializeErrors(
// deserializeErrors in react-router-dom/index.tsx :)
if (isRouteErrorResponse(val)) {
serialized[key] = { ...val, __type: "RouteErrorResponse" };
} else if (val instanceof Error) {
serialized[key] = {
message: val.message,
stack: val.stack,
__type: "Error",
};
} else {
serialized[key] = val;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/react-router/.eslintrc
Expand Up @@ -7,6 +7,7 @@
"__DEV__": true
},
"rules": {
"strict": 0
"strict": 0,
"no-restricted-syntax": ["error", "LogicalExpression[operator='??']"]
}
}
6 changes: 5 additions & 1 deletion packages/router/.eslintrc
Expand Up @@ -3,7 +3,11 @@
"browser": true,
"commonjs": true
},
"globals": {
"__DEV__": true
},
"rules": {
"strict": 0
"strict": 0,
"no-restricted-syntax": ["error", "LogicalExpression[operator='??']"]
}
}
35 changes: 30 additions & 5 deletions packages/router/router.ts
Expand Up @@ -1327,7 +1327,7 @@ export function createRouter(init: RouterInit): Router {
state.fetchers.set(key, loadingFetcher);
updateState({ fetchers: new Map(state.fetchers) });

return startRedirectNavigation(state, actionResult);
return startRedirectNavigation(state, actionResult, false, true);
}

// Process any non-redirect errors thrown
Expand Down Expand Up @@ -1587,13 +1587,23 @@ export function createRouter(init: RouterInit): Router {
async function startRedirectNavigation(
state: RouterState,
redirect: RedirectResult,
replace?: boolean
replace?: boolean,
isFetchActionRedirect?: boolean
) {
if (redirect.revalidate) {
isRevalidationRequired = true;
}

let redirectLocation = createLocation(state.location, redirect.location);
let redirectLocation = createLocation(
state.location,
redirect.location,
// TODO: This can be removed once we get rid of useTransition in Remix v2
isFetchActionRedirect
? {
isFetchActionRedirect: true,
}
: undefined
);
invariant(
redirectLocation,
"Expected a location on the redirect navigation"
Expand Down Expand Up @@ -2252,7 +2262,10 @@ export function unstable_createStaticHandler(
if (matchesToLoad.length === 0) {
return {
matches,
loaderData: {},
loaderData: matches.reduce(
(acc, m) => Object.assign(acc, { [m.route.id]: null }),
{}
),
errors: pendingActionError || null,
statusCode: 200,
loaderHeaders: {},
Expand Down Expand Up @@ -2280,7 +2293,9 @@ export function unstable_createStaticHandler(

// Can't do anything with these without the Remix side of things, so just
// cancel them for now
results.forEach((result) => {
let executedLoaders = new Set<string>();
results.forEach((result, i) => {
executedLoaders.add(matchesToLoad[i].route.id);
if (isDeferredResult(result)) {
result.deferredData.cancel();
}
Expand All @@ -2294,6 +2309,16 @@ export function unstable_createStaticHandler(
pendingActionError
);

// Add a null for any routes that didn't have loaders so we know they've been
// previously "executed" and qualify as a revalidation on subsequent
// invocations. This is mostly needed for SSr scenarios where there may be
// no server loader but there may be a client loaders to fetch code split bundles
matches.forEach((match) => {
if (!executedLoaders.has(match.route.id)) {
context.loaderData[match.route.id] = null;
}
});

return {
...context,
matches,
Expand Down