Skip to content

Commit 7508b08

Browse files
authored
Avoid hydration error if a server loader returned undefined (#13496)
1 parent b840885 commit 7508b08

File tree

4 files changed

+53
-1
lines changed

4 files changed

+53
-1
lines changed

.changeset/curvy-queens-hug.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router": patch
3+
---
4+
5+
Fix hydration error if a server `loader` returned `undefined`

integration/single-fetch-test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,24 @@ test.describe("single-fetch", () => {
316316
expect(await app.getHtml("#date")).toContain(ISO_DATE);
317317
});
318318

319+
test("allows SSR loaders to return undefined", async ({ page }) => {
320+
let fixture = await createFixture({
321+
files: {
322+
...files,
323+
"app/routes/_index.tsx": js`
324+
export function loader() {}
325+
export default function Index() {
326+
return <h1>Index</h1>
327+
}
328+
`,
329+
},
330+
});
331+
let appFixture = await createAppFixture(fixture);
332+
let app = new PlaywrightFixture(appFixture, page);
333+
await app.goto("/", true);
334+
expect(await app.getHtml("h1")).toContain("Index");
335+
});
336+
319337
test("loads proper data on client side navigation", async ({ page }) => {
320338
let fixture = await createFixture({
321339
files,

packages/react-router/__tests__/router/router-test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,35 @@ describe("a router", () => {
961961
router.dispose();
962962
});
963963

964+
it("allows routes to be initialized with undefined loaderData", async () => {
965+
let t = setup({
966+
routes: [
967+
{
968+
id: "root",
969+
path: "/",
970+
loader: true,
971+
},
972+
],
973+
hydrationData: {
974+
loaderData: {
975+
root: undefined,
976+
},
977+
},
978+
});
979+
980+
expect(t.router.state).toMatchObject({
981+
historyAction: "POP",
982+
location: {
983+
pathname: "/",
984+
},
985+
initialized: true,
986+
navigation: IDLE_NAVIGATION,
987+
loaderData: {
988+
root: undefined,
989+
},
990+
});
991+
});
992+
964993
it("handles interruptions of initial data load", async () => {
965994
let parentDfd = createDeferred();
966995
let parentSpy = jest.fn(() => parentDfd.promise);

packages/react-router/lib/router/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4822,7 +4822,7 @@ function shouldLoadRouteOnHydration(
48224822
return false;
48234823
}
48244824

4825-
let hasData = loaderData != null && loaderData[route.id] !== undefined;
4825+
let hasData = loaderData != null && route.id in loaderData;
48264826
let hasError = errors != null && errors[route.id] !== undefined;
48274827

48284828
// Don't run if we error'd during SSR

0 commit comments

Comments
 (0)