Laravel React项目app.jsx中使用RTK Query报错求助
RTK Query在Inertia.js根setup函数中调用报错的解决方法
问题描述
基于Laravel v10.x + ReactJS v18.2.0的项目,已集成Redux v8.1.2、Redux-Toolkit(RTK) v1.9.5及RTK Query,原本在FindTransactions组件中使用useGetTransactionsQuery可正常获取交易列表。但将该查询逻辑移至根级app.jsx的setup函数后,触发错误:Uncaught (in promise) TypeError: Je.current is null。
错误原因
- React Hook调用规则违反:
useGetTransactionsQuery是RTK Query封装的React Hook,而Inertia的setup是普通初始化函数,并非React组件或自定义Hook,在此处调用Hook违反了"Hook只能在React组件/自定义Hook顶层调用"的核心规则。 - RTK上下文未就绪:调用Hook时,Redux Provider尚未完成渲染,RTK Query依赖的内部上下文未初始化,导致内部引用(报错中的
Je.current)为null。
解决方案
方案1:在全局根组件中调用Hook
将查询逻辑移至项目的全局根组件(如共享的App组件)中,既符合Hook调用规则,又能全局触发请求:
// 示例:全局根组件(如Shared/App.jsx) import { useGetTransactionsQuery } from '@/Store/apiSlice'; export default function App({ children }) { // 在组件顶层调用Hook,全局触发交易列表查询 useGetTransactionsQuery(); return <>{children}</>; }
方案2:通过store.dispatch触发非Hook式查询
利用RTK Query提供的initiate方法,直接通过Redux store触发请求,无需依赖React Hook:
修改后的app.jsx代码:
import './bootstrap'; import '../css/app.css'; import '../css/my.css'; import { createRoot } from 'react-dom/client'; import { createInertiaApp } from '@inertiajs/react'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import store from '@/Store/Store'; import { Provider } from 'react-redux'; import { apiSlice } from '@/Store/apiSlice'; // 导入apiSlice而非Hook const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Venn'; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent(`./Pages/${name}.jsx`, import.meta.glob('./Pages/**/*.jsx')), setup({ el, App, props }) { // 直接通过store.dispatch触发查询 store.dispatch(apiSlice.endpoints.getTransactions.initiate()); const root = createRoot(el); root.render( <Provider store={store}> <App {...props} /> </Provider> ); }, progress: { color: '#4B5563', }, });
关键说明
- 非组件环境下触发RTK Query请求,必须使用
initiate方法,该方法会返回可取消的Promise,且数据会正常存入Redux store。 - 始终严格遵循React Hook的调用规则,避免在普通函数、条件判断或循环中调用Hook。
内容的提问来源于stack exchange,提问作者maganthro
相关产品推荐
相关产品推荐

