Remix路由间传参问题:如何从Table.tsx传参至Populate.tsx
Remix路由间传递数据的实现方案
是否需要Redux这类状态管理工具?
不需要。Remix本身提供了多种原生机制用于路由间数据传递,完全可以满足你的需求,无需引入额外状态管理库。
以下是几种适配不同场景的实现方式:
1. URL参数/查询参数传递(适用于页面跳转场景)
如果是从Table.tsx页面跳转到Interface.tsx页面,可以将数据通过URL查询参数携带,适合传递简单、非敏感的数据。
在
Table.tsx中发起跳转:import { Link } from "@remix-run/react"; export default function Table() { const tableData = { id: 1, name: "sample-data" }; return ( <Link to={{ pathname: "/interface", search: `?tableData=${encodeURIComponent(JSON.stringify(tableData))}` }} > 进入Interface页面 </Link> ); }在
Interface.tsx中读取参数并传递给Populate.tsx:import { useLoaderData } from "@remix-run/react"; import { json } from "@remix-run/node"; import Populate from "./Populate"; export async function loader({ request }) { const url = new URL(request.url); const dataStr = url.searchParams.get("tableData"); const tableData = dataStr ? JSON.parse(decodeURIComponent(dataStr)) : null; return json({ tableData }); } export default function Interface() { const { tableData } = useLoaderData<typeof loader>(); return <Populate data={tableData} />; }
注意:URL有长度限制,且数据会暴露在地址栏,不适合传递大量或敏感数据。
2. Session存储传递(适用于敏感/较大数据场景)
利用Remix的Session机制临时存储数据,适合传递敏感数据或较大数据,数据不会暴露在地址栏。
首先确保已配置Remix的Session(比如通过createCookieSessionStorage)。
在
Table.tsx中写入Session并跳转:import { redirect } from "@remix-run/node"; import { Form } from "@remix-run/react"; import { sessionStorage } from "~/services/session.server"; export async function action({ request }) { const formData = await request.formData(); const tableData = JSON.parse(formData.get("tableData") as string); const session = await sessionStorage.getSession(request.headers.get("Cookie")); session.set("tableData", tableData); return redirect("/interface", { headers: { "Set-Cookie": await sessionStorage.commitSession(session) } }); } export default function Table() { const tableData = { id: 1, name: "sensitive-data" }; return ( <Form method="post"> <input type="hidden" name="tableData" value={JSON.stringify(tableData)} /> <button type="submit">进入Interface页面</button> </Form> ); }在
Interface.tsx中读取Session数据并传递给Populate.tsx:import { useLoaderData } from "@remix-run/react"; import { json } from "@remix-run/node"; import { sessionStorage } from "~/services/session.server"; import Populate from "./Populate"; export async function loader({ request }) { const session = await sessionStorage.getSession(request.headers.get("Cookie")); const tableData = session.get("tableData"); // 用完后移除Session中的数据,避免长期占用 session.unset("tableData"); return json({ tableData }, { headers: { "Set-Cookie": await sessionStorage.commitSession(session) } }); } export default function Interface() { const { tableData } = useLoaderData<typeof loader>(); return <Populate data={tableData} />; }
3. 客户端路由State传递(适用于临时、非持久化数据)
通过Link组件的state属性传递数据,数据仅存储在客户端内存中,刷新页面后会丢失,适合临时传递非关键数据。
在
Table.tsx中传递state:import { Link } from "@remix-run/react"; export default function Table() { const tableData = { id: 1, name: "temp-data" }; return ( <Link to="/interface" state={{ tableData }}> 进入Interface页面 </Link> ); }在
Interface.tsx中读取state并传递给Populate.tsx:import { useLocation } from "@remix-run/react"; import Populate from "./Populate"; export default function Interface() { const location = useLocation(); const tableData = location.state?.tableData; return <Populate data={tableData} />; }
4. 父路由共享数据(适用于嵌套路由场景)
如果Table.tsx和Interface.tsx是同一父路由的子路由,可以在父路由的loader中处理数据,子路由通过useLoaderData或useMatches访问共享数据。
父路由(如
routes/_layout.tsx):import { Outlet, useLoaderData } from "@remix-run/react"; import { json } from "@remix-run/node"; import { sessionStorage } from "~/services/session.server"; export async function loader({ request }) { // 这里可以从Session或其他数据源获取共享数据 const session = await sessionStorage.getSession(request.headers.get("Cookie")); const sharedData = session.get("tableData"); return json({ sharedData }); } export default function Layout() { const { sharedData } = useLoaderData<typeof loader>(); // 通过Outlet的context传递给子路由 return <Outlet context={{ sharedData }} />; }在
Interface.tsx中读取父路由context:import { useOutletContext } from "@remix-run/react"; import Populate from "./Populate"; export default function Interface() { const { sharedData } = useOutletContext<{ sharedData: any }>(); return <Populate data={sharedData} />; }
内容的提问来源于stack exchange,提问作者Aarroonn
相关产品推荐
相关产品推荐

