在常规的 React 应用程序中,我会使用 Redux 来管理状态,在匹配 中的任何路由之前我会分派初始数据App,但是,在 Remix 中不建议使用 Redux,因此我useContext改为使用 Redux。
有没有一种方法可以调用加载器在/无需匹配任何路由之前获取初始数据(例如会话、对象等),然后将该数据存储在全局存储中context,然后可以由存储中的任何组件访问?这样,API 只会在应用程序初始化期间被调用。
我现在正在调用 的加载器中的初始数据root.tsx,获取它useLoaderData,然后将其作为道具传递给以StoreProvider在全局状态下分派它,但是,我认为不应该这样做。
export let loader: LoaderFunction = async ({ request }) => {
let user = await getUser(request);
const products = await db.product.findMany();
return { user: user?.username, products };
};
function App() {
const data = useLoaderData<LoaderData>();
return (
<html lang="en">
...
<StoreProvider initData={data}>
<body>
...
<Outlet />
<ScrollRestoration />
<Scripts />
{process.env.NODE_ENV === "development" && <LiveReload />}
</body>
</StoreProvider>
</html>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
小智 6
我认为在根路由加载器上加载数据是最好的方法。
如果您不喜欢这种方法,您也可以在entry.server 和entry.client 上获取。
例如在entry.client中你可能有这样的东西:
import { hydrate } from "react-dom";
import { RemixBrowser } from "remix";
hydrate(<RemixBrowser />, document);
Run Code Online (Sandbox Code Playgroud)
因此,您可以将其更改为在调用 Hydro 之前进行获取。
import { hydrate } from "react-dom";
import { RemixBrowser } from "remix";
fetch(YOUR_API_ENDPOINT)
.then(response => response.json())
.then(data => {
hydrate(
<YourContextProvider value={data}>
<RemixBrowser />
</YourContextProvider>,
document
)
});
Run Code Online (Sandbox Code Playgroud)
在entry.server中,您可以将handleRequest函数更改为如下所示:
import { renderToString } from "react-dom/server";
import { RemixServer } from "remix";
import type { EntryContext } from "remix";
export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
let response = await fetch(YOUR_API_ENDPOINT)
let data = await response.json()
let markup = renderToString(
<YourContextProvider value={data}>
<RemixServer context={remixContext} url={request.url} />
</YourContextProvider>
);
responseHeaders.set("Content-Type", "text/html");
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders
});
}
Run Code Online (Sandbox Code Playgroud)
通过在entry.client和entry.server上执行此操作,提取只会发生一次,并且永远不会再次触发。
我仍然建议您在根的加载器内执行此操作,以便在执行操作后可以再次获取它以保持数据更新。
| 归档时间: |
|
| 查看次数: |
6968 次 |
| 最近记录: |