最近发布了新的react-router
6.4,它能够在渲染组件之前加载数据。(https://reactrouter.com/en/main/start/overview#data-loading)
这看起来是一个很酷的功能。而且我想把它和RTK查询一起使用,因为我已经在使用Redux工具包了。
所以我想做一个基本的事情,我有加载帖子的API。我想加载它们,如果请求失败-重定向到其他页面。在react-router
6.4中,这一切都可以在路由器中完成(https://reactrouter.com/en/main/start/overview#redirects)。
Router不在react的范围内,因此我无法使用rtk query提供的钩子,这意味着我必须使用没有钩子的rtk query,根据文档,这是完全可能的(https://redux-toolkit.js.org/rtk-query/usage/usage-without-react-hooks)
所以我的问题是,如何在react-router
加载器中读取请求的状态。我可以使用钩子读取组件中的状态,但这会使组件“脏”,并将逻辑分散到整个应用程序中。
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { Provider } from "react-redux";
import { store } from "./redux/redux";
import { Comments } from "./Comments";
import { Posts } from "./Posts";
import { Root } from "./Root";
import { postsApi } from "./redux/redux";
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
},
{
path: "posts",
element: <Posts />,
loader: () => {
store.dispatch(postsApi.endpoints.getPosts.initiate());
const request = postsApi.endpoints.getPosts.select()(store);
console.log(request);
return request;
},
},
{
path: "/comments",
element: <Comments />,
},
]);
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<Provider store={store}>
<RouterProvider router={router} />
</Provider>
);
我尝试使用文档中的示例,但我总是在控制台中得到“未初始化”状态,就像从未发出过请求一样,但它确实是,我可以在redux开发工具中看到数据。而且我还得到错误“在state.postsApi
处未找到数据。您忘记将reducer添加到存储区吗?”
2条答案
按热度按时间hi3rlvi21#
你可能会做一些沿着的事情
请注意,我不会在这里访问数据,您可能也不应该访问,虽然在
await promise
之后它将可用,但我将仅在数据出现时使用加载器-然后使用组件中的常规useMyEndpointQuery(someArgument)
访问该数据。您需要使用钩子,该高速缓存知道您的组件实际上正在使用该数据-否则它将在60秒后从缓存中删除(或者如果您从未取消订阅,它将永远不会被删除)。
此时,将数据从
loader
函数传递到组件中并没有什么真实的好处-无论如何,组件已经能够通过钩子访问数据了。所以我的建议是:启动并等待从
loader
获取数据,但实际上像以前一样从组件访问数据。3zwjbxry2#
您的思路是正确的,但是您需要对dispatch返回的promise调用unwrap(),如果成功则返回结果,如果不成功则抛出。