From 5b02e7d33d9251c74a96841979f4079694d19e6e Mon Sep 17 00:00:00 2001
From: Matt Brophy Loading... Loading... Loading... Loading... Should not see me Root Loading...
@@ -33,6 +35,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-0",
"index": undefined,
"lazy": undefined,
@@ -43,6 +46,7 @@ describe("creating routes from JSX", () => {
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"element":
@@ -51,6 +55,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-1",
"index": undefined,
"lazy": undefined,
@@ -61,12 +66,14 @@ describe("creating routes from JSX", () => {
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"children": [
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"element":
@@ -75,6 +82,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-2-0",
"index": true,
"lazy": undefined,
@@ -85,6 +93,7 @@ describe("creating routes from JSX", () => {
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"element":
@@ -93,6 +102,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-2-1",
"index": undefined,
"lazy": undefined,
@@ -105,6 +115,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-2",
"index": undefined,
"lazy": undefined,
@@ -117,6 +128,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0",
"index": undefined,
"lazy": undefined,
@@ -153,12 +165,14 @@ describe("creating routes from JSX", () => {
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"children": [
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"element":
@@ -167,6 +181,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-0",
"index": undefined,
"lazy": undefined,
@@ -177,12 +192,14 @@ describe("creating routes from JSX", () => {
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": undefined,
"caseSensitive": undefined,
"children": [
{
"Component": undefined,
"ErrorBoundary": undefined,
+ "HydrateFallback": undefined,
"action": [Function],
"caseSensitive": undefined,
"element":
@@ -191,6 +208,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-1-0",
"index": true,
"lazy": undefined,
@@ -203,6 +221,7 @@ describe("creating routes from JSX", () => {
"errorElement": undefined,
"handle": undefined,
"hasErrorBoundary": false,
+ "hydrateFallbackElement": undefined,
"id": "0-1",
"index": undefined,
"lazy": undefined,
@@ -217,6 +236,7 @@ describe("creating routes from JSX", () => {
,
"handle": undefined,
"hasErrorBoundary": true,
+ "hydrateFallbackElement": undefined,
"id": "0",
"index": undefined,
"lazy": undefined,
diff --git a/packages/react-router/__tests__/data-memory-router-test.tsx b/packages/react-router/__tests__/data-memory-router-test.tsx
index fed0bbc1e8..adf92675a2 100644
--- a/packages/react-router/__tests__/data-memory-router-test.tsx
+++ b/packages/react-router/__tests__/data-memory-router-test.tsx
@@ -313,11 +313,15 @@ describe("createMemoryRouter", () => {
`);
});
- it("renders fallbackElement while first data fetch happens", async () => {
+ it("renders hydrateFallbackElement while first data fetch happens", async () => {
let fooDefer = createDeferred();
let router = createMemoryRouter(
createRoutesFromElements(
- {`Home - ${data}`}
- {`Index - ${data}`}
;
- },
- },
- ],
- },
- ],
- {
- hydrationData: {
- loaderData: {
- root: "HYDRATED ROOT",
- },
- },
- }
- );
- let { container } = render(
- Home - HYDRATED ROOT
-
-
- Index - undefined
-
- {`Home - ${data}`}
- {`Index - ${data}`}
;
- },
- },
- ],
- },
- ],
- {
- hydrationData: {
- loaderData: {
- root: "HYDRATED ROOT",
- },
- },
- future: {
- v7_partialHydration: true,
- },
- }
- );
- let { container } = render(
-
- Root Loading... -
-Index Loading...
, - async lazy() { - await tick(); - return { - loader: () => dfd.promise, - Component() { - let data = useLoaderData() as string; - returnIndex Loading...
, + async lazy() { + await tick(); + return { + loader: () => dfd.promise, + Component() { + let data = useLoaderData() as string; + returnLoading...
, - children: [ - { - id: "index", - index: true, - async lazy() { - await tick(); - return { - loader: () => dfd.promise, - Component() { - let data = useLoaderData() as string; - returnLoading...
, + children: [ + { + id: "index", + index: true, + async lazy() { + await tick(); + return { + loader: () => dfd.promise, + Component() { + let data = useLoaderData() as string; + returnMessage: {data.message}; @@ -148,6 +149,7 @@ test("can pass context values", async () => { [ { path: "/", + HydrateFallback: () => null, Component() { let data = useLoaderData() as { context: string }; return ( diff --git a/packages/react-router/__tests__/router/route-fallback-test.ts b/packages/react-router/__tests__/router/route-fallback-test.ts index ebe98deb38..05ac55824b 100644 --- a/packages/react-router/__tests__/router/route-fallback-test.ts +++ b/packages/react-router/__tests__/router/route-fallback-test.ts @@ -44,480 +44,257 @@ afterEach(() => { router.dispose(); }); -describe("future.v7_partialHydration", () => { - describe("when set to false (default behavior)", () => { - it("starts with initialized=true when no loaders exist without hydrationData", async () => { - router = createRouter({ - routes: [ - { - id: "root", - path: "/", - }, - ], - history: createMemoryHistory(), - }); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - matches: [{ pathname: "/", route: { id: "root" } }], - initialized: true, - navigation: { state: "idle" }, - }); - }); - - it("starts with initialized=false when loaders exist without hydrationData", async () => { - router = createRouter({ - routes: [ - { - id: "root", - path: "/", - loader: () => Promise.resolve("LOADER DATA"), - }, - ], - history: createMemoryHistory(), - }); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: {}, - matches: [{ pathname: "/", route: { id: "root" } }], - initialized: false, - navigation: { state: "idle" }, - }); - - router.initialize(); - await tick(); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { root: "LOADER DATA" }, - matches: [{ pathname: "/", route: { id: "root" } }], - initialized: true, - navigation: { state: "idle" }, - }); - }); - - it("starts with initialized=true when loaders exist with full hydrationData", async () => { - let spy = jest.fn(); - router = createRouter({ - routes: [ - { - id: "root", - path: "/", - loader: spy, - }, - ], - history: createMemoryHistory(), - hydrationData: { - loaderData: { root: "LOADER DATA" }, +describe("route HydrateFallback", () => { + it("starts with initialized=false, runs unhydrated loaders with partial hydrationData", async () => { + let spy = jest.fn(); + let shouldRevalidateSpy = jest.fn((args) => args.defaultShouldRevalidate); + let dfd = createDeferred(); + router = createRouter({ + routes: [ + { + id: "root", + path: "/", + loader: spy, + shouldRevalidate: shouldRevalidateSpy, + children: [ + { + id: "index", + index: true, + loader: () => dfd.promise, + }, + ], }, - }); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { root: "LOADER DATA" }, - matches: [{ pathname: "/", route: { id: "root" } }], - initialized: true, - navigation: { state: "idle" }, - }); - expect(spy).not.toHaveBeenCalled(); - }); - - it("starts with initialized=true when loaders exist with full hydrationData (+actions/errors)", async () => { - let spy = jest.fn(); - router = createRouter({ - routes: [ - { - id: "root", - path: "/", - hasErrorBoundary: true, - loader: spy, - action: spy, - }, - ], - history: createMemoryHistory(), - hydrationData: { - loaderData: { root: "LOADER DATA" }, - actionData: { root: "ACTION DATA" }, - errors: { root: new Error("lol") }, + ], + history: createMemoryHistory(), + hydrationData: { + loaderData: { + root: "LOADER DATA", + // No loaderData provided for index route }, - }); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { root: "LOADER DATA" }, - actionData: { root: "ACTION DATA" }, - errors: { root: new Error("lol") }, - matches: [{ pathname: "/", route: { id: "root" } }], - initialized: true, - navigation: { state: "idle" }, - }); - expect(spy).not.toHaveBeenCalled(); + }, }); - // This is needed because we can't detect valid "I have a loader" routes - // in Remix since all routes have a loader to fetch JS bundles but may not - // actually provide any loaderData - it("starts with initialized=true when loaders exist with partial hydration data", async () => { - let parentSpy = jest.fn(); - let childSpy = jest.fn(); - let router = createRouter({ - history: createMemoryHistory({ initialEntries: ["/child"] }), - routes: [ - { - path: "/", - loader: parentSpy, - children: [ - { - path: "child", - loader: childSpy, - }, - ], - }, - ], - hydrationData: { - loaderData: { - "0": "PARENT DATA", - }, - }, - }); - router.initialize(); + let subscriberSpy = jest.fn(); + router.subscribe(subscriberSpy); - expect(parentSpy.mock.calls.length).toBe(0); - expect(childSpy.mock.calls.length).toBe(0); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: expect.objectContaining({ pathname: "/child" }), - matches: [{ route: { path: "/" } }, { route: { path: "child" } }], - initialized: true, - navigation: IDLE_NAVIGATION, - }); - expect(router.state.loaderData).toEqual({ - "0": "PARENT DATA", - }); - - router.dispose(); + // Start with initialized:false + expect(router.state).toMatchObject({ + historyAction: "POP", + location: { pathname: "/" }, + loaderData: { root: "LOADER DATA" }, + initialized: false, + navigation: { state: "idle" }, }); - it("does not kick off initial data load if errors exist", async () => { - let consoleWarnSpy = jest - .spyOn(console, "warn") - .mockImplementation(() => {}); - let parentDfd = createDeferred(); - let parentSpy = jest.fn(() => parentDfd.promise); - let childDfd = createDeferred(); - let childSpy = jest.fn(() => childDfd.promise); - let router = createRouter({ - history: createMemoryHistory({ initialEntries: ["/child"] }), - routes: [ - { - path: "/", - loader: parentSpy, - children: [ - { - path: "child", - loader: childSpy, - }, - ], - }, - ], - hydrationData: { - errors: { - "0": "PARENT ERROR", - }, - loaderData: { - "0-0": "CHILD_DATA", - }, - }, - }); - router.initialize(); + // Initialize/kick off data loads due to partial hydrationData + router.initialize(); + await dfd.resolve("INDEX DATA"); + expect(router.state).toMatchObject({ + historyAction: "POP", + location: { pathname: "/" }, + loaderData: { root: "LOADER DATA", index: "INDEX DATA" }, + initialized: true, + navigation: { state: "idle" }, + }); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - expect(parentSpy).not.toHaveBeenCalled(); - expect(childSpy).not.toHaveBeenCalled(); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: expect.objectContaining({ pathname: "/child" }), - matches: [{ route: { path: "/" } }, { route: { path: "child" } }], - initialized: true, - navigation: IDLE_NAVIGATION, - errors: { - "0": "PARENT ERROR", - }, - loaderData: { - "0-0": "CHILD_DATA", - }, - }); + // Root was not re-called + expect(shouldRevalidateSpy).not.toHaveBeenCalled(); + expect(spy).not.toHaveBeenCalled(); - router.dispose(); - consoleWarnSpy.mockReset(); + // Ensure we don't go into a navigating state during initial calls of + // the loaders + expect(subscriberSpy).toHaveBeenCalledTimes(1); + expect(subscriberSpy.mock.calls[0][0]).toMatchObject({ + loaderData: { + index: "INDEX DATA", + root: "LOADER DATA", + }, + navigation: IDLE_NAVIGATION, }); }); - describe("when set to true", () => { - it("starts with initialized=false, runs unhydrated loaders with partial hydrationData", async () => { - let spy = jest.fn(); - let shouldRevalidateSpy = jest.fn((args) => args.defaultShouldRevalidate); - let dfd = createDeferred(); - router = createRouter({ - routes: [ - { - id: "root", - path: "/", - loader: spy, - shouldRevalidate: shouldRevalidateSpy, - children: [ - { - id: "index", - index: true, - loader: () => dfd.promise, - }, - ], - }, - ], - history: createMemoryHistory(), - hydrationData: { - loaderData: { - root: "LOADER DATA", - // No loaderData provided for index route - }, - }, - future: { - v7_partialHydration: true, + it("starts with initialized=false, runs hydrated loaders when loader.hydrate=true", async () => { + let spy = jest.fn(); + let shouldRevalidateSpy = jest.fn((args) => args.defaultShouldRevalidate); + let dfd = createDeferred(); + let indexLoader: LoaderFunction = () => dfd.promise; + indexLoader.hydrate = true; + router = createRouter({ + routes: [ + { + id: "root", + path: "/", + loader: spy, + shouldRevalidate: shouldRevalidateSpy, + children: [ + { + id: "index", + index: true, + loader: indexLoader, + }, + ], }, - }); - - let subscriberSpy = jest.fn(); - router.subscribe(subscriberSpy); - - // Start with initialized:false - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { root: "LOADER DATA" }, - initialized: false, - navigation: { state: "idle" }, - }); - - // Initialize/kick off data loads due to partial hydrationData - router.initialize(); - await dfd.resolve("INDEX DATA"); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { root: "LOADER DATA", index: "INDEX DATA" }, - initialized: true, - navigation: { state: "idle" }, - }); - - // Root was not re-called - expect(shouldRevalidateSpy).not.toHaveBeenCalled(); - expect(spy).not.toHaveBeenCalled(); - - // Ensure we don't go into a navigating state during initial calls of - // the loaders - expect(subscriberSpy).toHaveBeenCalledTimes(1); - expect(subscriberSpy.mock.calls[0][0]).toMatchObject({ + ], + history: createMemoryHistory(), + hydrationData: { loaderData: { - index: "INDEX DATA", root: "LOADER DATA", + index: "INDEX INITIAL", }, - navigation: IDLE_NAVIGATION, - }); + }, }); - it("starts with initialized=false, runs hydrated loaders when loader.hydrate=true", async () => { - let spy = jest.fn(); - let shouldRevalidateSpy = jest.fn((args) => args.defaultShouldRevalidate); - let dfd = createDeferred(); - let indexLoader: LoaderFunction = () => dfd.promise; - indexLoader.hydrate = true; - router = createRouter({ - routes: [ - { - id: "root", - path: "/", - loader: spy, - shouldRevalidate: shouldRevalidateSpy, - children: [ - { - id: "index", - index: true, - loader: indexLoader, - }, - ], - }, - ], - history: createMemoryHistory(), - hydrationData: { - loaderData: { - root: "LOADER DATA", - index: "INDEX INITIAL", - }, - }, - future: { - v7_partialHydration: true, - }, - }); - - let subscriberSpy = jest.fn(); - router.subscribe(subscriberSpy); + let subscriberSpy = jest.fn(); + router.subscribe(subscriberSpy); - // Start with initialized:false - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { - root: "LOADER DATA", - index: "INDEX INITIAL", - }, - initialized: false, - navigation: { state: "idle" }, - }); + // Start with initialized:false + expect(router.state).toMatchObject({ + historyAction: "POP", + location: { pathname: "/" }, + loaderData: { + root: "LOADER DATA", + index: "INDEX INITIAL", + }, + initialized: false, + navigation: { state: "idle" }, + }); - // Initialize/kick off data loads due to partial hydrationData - router.initialize(); - await dfd.resolve("INDEX UPDATED"); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: { pathname: "/" }, - loaderData: { - root: "LOADER DATA", - index: "INDEX UPDATED", - }, - initialized: true, - navigation: { state: "idle" }, - }); + // Initialize/kick off data loads due to partial hydrationData + router.initialize(); + await dfd.resolve("INDEX UPDATED"); + expect(router.state).toMatchObject({ + historyAction: "POP", + location: { pathname: "/" }, + loaderData: { + root: "LOADER DATA", + index: "INDEX UPDATED", + }, + initialized: true, + navigation: { state: "idle" }, + }); - // Root was not re-called - expect(shouldRevalidateSpy).not.toHaveBeenCalled(); - expect(spy).not.toHaveBeenCalled(); + // Root was not re-called + expect(shouldRevalidateSpy).not.toHaveBeenCalled(); + expect(spy).not.toHaveBeenCalled(); - // Ensure we don't go into a navigating state during initial calls of - // the loaders - expect(subscriberSpy).toHaveBeenCalledTimes(1); - expect(subscriberSpy.mock.calls[0][0]).toMatchObject({ - loaderData: { - index: "INDEX UPDATED", - root: "LOADER DATA", - }, - navigation: IDLE_NAVIGATION, - }); + // Ensure we don't go into a navigating state during initial calls of + // the loaders + expect(subscriberSpy).toHaveBeenCalledTimes(1); + expect(subscriberSpy.mock.calls[0][0]).toMatchObject({ + loaderData: { + index: "INDEX UPDATED", + root: "LOADER DATA", + }, + navigation: IDLE_NAVIGATION, }); + }); - it("does not kick off initial data load if errors exist (parent error)", async () => { - let consoleWarnSpy = jest - .spyOn(console, "warn") - .mockImplementation(() => {}); - let parentDfd = createDeferred(); - let parentSpy = jest.fn(() => parentDfd.promise); - let childDfd = createDeferred(); - let childSpy = jest.fn(() => childDfd.promise); - let router = createRouter({ - history: createMemoryHistory({ initialEntries: ["/child"] }), - routes: [ - { - path: "/", - loader: parentSpy, - children: [ - { - path: "child", - loader: childSpy, - }, - ], - }, - ], - future: { - v7_partialHydration: true, - }, - hydrationData: { - errors: { - "0": "PARENT ERROR", - }, - loaderData: { - "0-0": "CHILD_DATA", - }, + it("does not kick off initial data load if errors exist (parent error)", async () => { + let consoleWarnSpy = jest + .spyOn(console, "warn") + .mockImplementation(() => {}); + let parentDfd = createDeferred(); + let parentSpy = jest.fn(() => parentDfd.promise); + let childDfd = createDeferred(); + let childSpy = jest.fn(() => childDfd.promise); + let router = createRouter({ + history: createMemoryHistory({ initialEntries: ["/child"] }), + routes: [ + { + path: "/", + loader: parentSpy, + children: [ + { + path: "child", + loader: childSpy, + }, + ], }, - }); - router.initialize(); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - expect(parentSpy).not.toHaveBeenCalled(); - expect(childSpy).not.toHaveBeenCalled(); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: expect.objectContaining({ pathname: "/child" }), - matches: [{ route: { path: "/" } }, { route: { path: "child" } }], - initialized: true, - navigation: IDLE_NAVIGATION, + ], + hydrationData: { errors: { "0": "PARENT ERROR", }, loaderData: { "0-0": "CHILD_DATA", }, - }); + }, + }); + router.initialize(); - router.dispose(); - consoleWarnSpy.mockReset(); + expect(consoleWarnSpy).not.toHaveBeenCalled(); + expect(parentSpy).not.toHaveBeenCalled(); + expect(childSpy).not.toHaveBeenCalled(); + expect(router.state).toMatchObject({ + historyAction: "POP", + location: expect.objectContaining({ pathname: "/child" }), + matches: [{ route: { path: "/" } }, { route: { path: "child" } }], + initialized: true, + navigation: IDLE_NAVIGATION, + errors: { + "0": "PARENT ERROR", + }, + loaderData: { + "0-0": "CHILD_DATA", + }, }); - it("does not kick off initial data load if errors exist (bubbled child error)", async () => { - let consoleWarnSpy = jest - .spyOn(console, "warn") - .mockImplementation(() => {}); - let parentDfd = createDeferred(); - let parentSpy = jest.fn(() => parentDfd.promise); - let childDfd = createDeferred(); - let childSpy = jest.fn(() => childDfd.promise); - let router = createRouter({ - history: createMemoryHistory({ initialEntries: ["/child"] }), - routes: [ - { - path: "/", - loader: parentSpy, - children: [ - { - path: "child", - loader: childSpy, - }, - ], - }, - ], - future: { - v7_partialHydration: true, - }, - hydrationData: { - errors: { - "0": "CHILD ERROR", - }, - loaderData: { - "0": "PARENT DATA", - }, - }, - }); - router.initialize(); + router.dispose(); + consoleWarnSpy.mockReset(); + }); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - expect(parentSpy).not.toHaveBeenCalled(); - expect(childSpy).not.toHaveBeenCalled(); - expect(router.state).toMatchObject({ - historyAction: "POP", - location: expect.objectContaining({ pathname: "/child" }), - matches: [{ route: { path: "/" } }, { route: { path: "child" } }], - initialized: true, - navigation: IDLE_NAVIGATION, + it("does not kick off initial data load if errors exist (bubbled child error)", async () => { + let consoleWarnSpy = jest + .spyOn(console, "warn") + .mockImplementation(() => {}); + let parentDfd = createDeferred(); + let parentSpy = jest.fn(() => parentDfd.promise); + let childDfd = createDeferred(); + let childSpy = jest.fn(() => childDfd.promise); + let router = createRouter({ + history: createMemoryHistory({ initialEntries: ["/child"] }), + routes: [ + { + path: "/", + loader: parentSpy, + children: [ + { + path: "child", + loader: childSpy, + }, + ], + }, + ], + hydrationData: { errors: { "0": "CHILD ERROR", }, loaderData: { "0": "PARENT DATA", }, - }); + }, + }); + router.initialize(); - router.dispose(); - consoleWarnSpy.mockReset(); + expect(consoleWarnSpy).not.toHaveBeenCalled(); + expect(parentSpy).not.toHaveBeenCalled(); + expect(childSpy).not.toHaveBeenCalled(); + expect(router.state).toMatchObject({ + historyAction: "POP", + location: expect.objectContaining({ pathname: "/child" }), + matches: [{ route: { path: "/" } }, { route: { path: "child" } }], + initialized: true, + navigation: IDLE_NAVIGATION, + errors: { + "0": "CHILD ERROR", + }, + loaderData: { + "0": "PARENT DATA", + }, }); + + router.dispose(); + consoleWarnSpy.mockReset(); }); it("does not kick off initial data load for routes that don't have loaders", async () => { @@ -539,9 +316,6 @@ describe("future.v7_partialHydration", () => { ], }, ], - future: { - v7_partialHydration: true, - }, hydrationData: { loaderData: { "0": "PARENT DATA", diff --git a/packages/react-router/__tests__/router/router-test.ts b/packages/react-router/__tests__/router/router-test.ts index 49ba868309..eb733f9989 100644 --- a/packages/react-router/__tests__/router/router-test.ts +++ b/packages/react-router/__tests__/router/router-test.ts @@ -947,10 +947,7 @@ describe("a router", () => { historyAction: "POP", location: expect.objectContaining({ pathname: "/child" }), initialized: false, - navigation: { - state: "loading", - location: { pathname: "/child" }, - }, + navigation: IDLE_NAVIGATION, }); expect(router.state.loaderData).toEqual({}); @@ -959,10 +956,7 @@ describe("a router", () => { historyAction: "POP", location: expect.objectContaining({ pathname: "/child" }), initialized: false, - navigation: { - state: "loading", - location: { pathname: "/child" }, - }, + navigation: IDLE_NAVIGATION, }); expect(router.state.loaderData).toEqual({}); @@ -1016,10 +1010,7 @@ describe("a router", () => { historyAction: "POP", location: expect.objectContaining({ pathname: "/child" }), initialized: false, - navigation: { - state: "loading", - location: { pathname: "/child" }, - }, + navigation: IDLE_NAVIGATION, }); expect(router.state.loaderData).toEqual({}); @@ -1028,10 +1019,7 @@ describe("a router", () => { historyAction: "POP", location: expect.objectContaining({ pathname: "/child" }), initialized: false, - navigation: { - state: "loading", - location: { pathname: "/child" }, - }, + navigation: IDLE_NAVIGATION, }); expect(router.state.loaderData).toEqual({}); @@ -1118,10 +1106,7 @@ describe("a router", () => { historyAction: "POP", location: expect.objectContaining({ pathname: "/", hash: "#hash" }), initialized: false, - navigation: { - state: "loading", - location: { pathname: "/", hash: "#hash" }, - }, + navigation: IDLE_NAVIGATION, }); expect(router.state.loaderData).toEqual({}); diff --git a/packages/react-router/lib/components.tsx b/packages/react-router/lib/components.tsx index 2528553e6b..e015b8d1cd 100644 --- a/packages/react-router/lib/components.tsx +++ b/packages/react-router/lib/components.tsx @@ -847,6 +847,8 @@ export function createRoutesFromChildren( path: element.props.path, loader: element.props.loader, action: element.props.action, + hydrateFallbackElement: element.props.hydrateFallbackElement, + HydrateFallback: element.props.HydrateFallback, errorElement: element.props.errorElement, ErrorBoundary: element.props.ErrorBoundary, hasErrorBoundary: diff --git a/packages/react-router/lib/dom/lib.tsx b/packages/react-router/lib/dom/lib.tsx index fbb27ed1b8..cb62d8bd83 100644 --- a/packages/react-router/lib/dom/lib.tsx +++ b/packages/react-router/lib/dom/lib.tsx @@ -307,7 +307,6 @@ class Deferred