-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
feat: add custom response decoding option #11086
Changes from 3 commits
3b3c9b5
daf4c0f
87b188c
1ea2b78
8925423
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
"react-router-dom": minor | ||
"react-router": minor | ||
"@remix-run/router": minor | ||
--- | ||
|
||
add decodeResponse option to createStaticHandler, createStaticRouter, createBrowserRouter, and createHashRouter |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -730,6 +730,109 @@ function testDomRouter( | |||||
`); | ||||||
}); | ||||||
|
||||||
it("executes route loaders on navigation with decodeRoute", async () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
let barDefer = createDeferred(); | ||||||
|
||||||
let router = createTestRouter( | ||||||
createRoutesFromElements( | ||||||
<Route path="/" element={<Layout />}> | ||||||
<Route path="foo" element={<Foo />} /> | ||||||
<Route | ||||||
path="bar" | ||||||
loader={() => barDefer.promise} | ||||||
element={<Bar />} | ||||||
/> | ||||||
</Route> | ||||||
), | ||||||
{ | ||||||
window: getWindow("/foo"), | ||||||
async decodeResponse(response, defaultDecode) { | ||||||
let contentType = response.headers.get("Content-Type"); | ||||||
if (contentType === "text/custom") { | ||||||
const text = await response.text(); | ||||||
switch (text) { | ||||||
case "bar": | ||||||
return { message: "Bar Loader" }; | ||||||
default: | ||||||
return text; | ||||||
} | ||||||
} | ||||||
|
||||||
return defaultDecode(); | ||||||
}, | ||||||
} | ||||||
); | ||||||
let { container } = render(<RouterProvider router={router} />); | ||||||
|
||||||
function Layout() { | ||||||
let navigation = useNavigation(); | ||||||
return ( | ||||||
<div> | ||||||
<Link to="/bar">Link to Bar</Link> | ||||||
<div id="output"> | ||||||
<p>{navigation.state}</p> | ||||||
<Outlet /> | ||||||
</div> | ||||||
</div> | ||||||
); | ||||||
} | ||||||
|
||||||
function Foo() { | ||||||
return <h1>Foo</h1>; | ||||||
} | ||||||
function Bar() { | ||||||
let data = useLoaderData() as { message: string }; | ||||||
return <h1>{data.message}</h1>; | ||||||
} | ||||||
|
||||||
expect(getHtml(container.querySelector("#output")!)) | ||||||
.toMatchInlineSnapshot(` | ||||||
"<div | ||||||
id="output" | ||||||
> | ||||||
<p> | ||||||
idle | ||||||
</p> | ||||||
<h1> | ||||||
Foo | ||||||
</h1> | ||||||
</div>" | ||||||
`); | ||||||
|
||||||
fireEvent.click(screen.getByText("Link to Bar")); | ||||||
expect(getHtml(container.querySelector("#output")!)) | ||||||
.toMatchInlineSnapshot(` | ||||||
"<div | ||||||
id="output" | ||||||
> | ||||||
<p> | ||||||
loading | ||||||
</p> | ||||||
<h1> | ||||||
Foo | ||||||
</h1> | ||||||
</div>" | ||||||
`); | ||||||
|
||||||
barDefer.resolve( | ||||||
new Response("bar", { headers: { "Content-Type": "text/custom" } }) | ||||||
); | ||||||
await waitFor(() => screen.getByText("idle")); | ||||||
expect(getHtml(container.querySelector("#output")!)) | ||||||
.toMatchInlineSnapshot(` | ||||||
"<div | ||||||
id="output" | ||||||
> | ||||||
<p> | ||||||
idle | ||||||
</p> | ||||||
<h1> | ||||||
Bar Loader | ||||||
</h1> | ||||||
</div>" | ||||||
`); | ||||||
}); | ||||||
|
||||||
it("executes lazy route loaders on navigation", async () => { | ||||||
let barDefer = createDeferred(); | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ import { | |
} from "react-router"; | ||
import type { | ||
BrowserHistory, | ||
DecodeResponseFunction, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be re-exported from react-router-dom? |
||
Fetcher, | ||
FormEncType, | ||
FormMethod, | ||
|
@@ -231,6 +232,7 @@ interface DOMRouterOpts { | |
future?: Partial<Omit<RouterFutureConfig, "v7_prependBasename">>; | ||
hydrationData?: HydrationState; | ||
window?: Window; | ||
decodeResponse?: DecodeResponseFunction; | ||
} | ||
|
||
export function createBrowserRouter( | ||
|
@@ -248,6 +250,7 @@ export function createBrowserRouter( | |
routes, | ||
mapRouteProperties, | ||
window: opts?.window, | ||
decodeResponse: opts?.decodeResponse, | ||
}).initialize(); | ||
} | ||
|
||
|
@@ -266,6 +269,7 @@ export function createHashRouter( | |
routes, | ||
mapRouteProperties, | ||
window: opts?.window, | ||
decodeResponse: opts?.decodeResponse, | ||
}).initialize(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ import type { | |
ActionFunctionArgs, | ||
Blocker, | ||
BlockerFunction, | ||
DecodeResponseFunction, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be re-exported? |
||
ErrorResponse, | ||
Fetcher, | ||
HydrationState, | ||
|
@@ -272,6 +273,7 @@ export function createMemoryRouter( | |
hydrationData?: HydrationState; | ||
initialEntries?: InitialEntry[]; | ||
initialIndex?: number; | ||
decodeResponse?: DecodeResponseFunction; | ||
} | ||
): RemixRouter { | ||
return createRouter({ | ||
|
@@ -287,6 +289,7 @@ export function createMemoryRouter( | |
hydrationData: opts?.hydrationData, | ||
routes, | ||
mapRouteProperties, | ||
decodeResponse: opts?.decodeResponse, | ||
}).initialize(); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a
Type Declaration
section a bit higher up that we should add this too also