如何在React Router 6.4中不使用钩子读取RTK Query状态
问题解决步骤
1. 先修复Store的RTK Query配置错误
你收到的错误提示翻译为:“在state.postsApi未找到数据,是否忘记将reducer添加到store?”
这个报错的核心原因是Redux Store没有正确注册RTK Query生成的reducer和中间件,必须在创建store时补充配置:
修改你的./redux/redux.ts文件:
import { configureStore } from '@reduxjs/toolkit'; import { postsApi } from './postsApi'; // 对应你的postsApi定义文件 export const store = configureStore({ reducer: { // 必须添加RTK Query生成的reducer,使用reducerPath作为key [postsApi.reducerPath]: postsApi.reducer, // 其他自定义reducer可放在这里 }, // 必须添加RTK Query的中间件,处理缓存、请求失效等逻辑 middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(postsApi.middleware), });
2. 修复Loader中的异步逻辑问题
你当前代码里,dispatch请求后立刻调用select,但RTK Query的请求是异步的,此时Store还未更新,所以拿到的状态是uninitialized。
React Router的loader支持异步函数,你可以利用initiate()返回的Promise(调用unwrap()后,请求成功会返回数据,失败则抛出错误),实现等待请求完成并处理结果:
修改路由的loader逻辑:
import { redirect } from 'react-router-dom'; const router = createBrowserRouter([ // ...其他路由配置 { path: "posts", element: <Posts />, loader: async () => { try { // 发起请求并等待完成,unwrap()自动处理成功/失败分支 const data = await store.dispatch(postsApi.endpoints.getPosts.initiate()).unwrap(); // 请求成功,返回数据给组件使用 return { data }; } catch (error) { // 请求失败,直接重定向到目标页面(比如首页) return redirect("/"); } }, }, ]);
3. 在组件中读取Loader返回的数据
如果需要在Posts组件中使用loader返回的结果,用React Router的useLoaderData()钩子即可:
import { useLoaderData } from 'react-router-dom'; export function Posts() { const { data } = useLoaderData(); return ( <div> {data.map(post => ( <div key={post.id}>{post.title}</div> ))} </div> ); }
额外说明
- 若需要在loader中获取更详细的请求状态(如加载中、缓存状态),可在请求完成后通过
postsApi.endpoints.getPosts.select()(store)读取,但对于你的重定向需求,try/catch分支已经足够覆盖成功/失败场景。 - RTK Query的
initiate()返回的对象自带unwrap()方法,专门用于简化异步请求的结果处理,完美适配React Router loader的异步逻辑。
内容的提问来源于stack exchange,提问作者Yastrebtsov
相关产品推荐
相关产品推荐

