'Refactoring thunk slices to RTK-Query causing top-level API calls invalid
I'm working on an app using react / redux / redux-toolkit.
Until now, I was using createAsyncThunk to wrap API calls, but for more convenience I decided to use RTK-Query.
It works fine in most cases. However, there's a situation in which I'm unable to make it work. This is when I want the API call to be done directly at the app startup, in the index.js file, as follows :
Working version :
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from "react-redux";
import App from './App';
import store from './store';
import {fetchUserInfo} from "./features/user";
store.dispatch(fetchUserInfo());
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('root')
);
Here, the store.dispatch(fetchUserInfo()); is placed here so that store.user.info will be available in any subsequent component.
The definition of the fetchUserInfo() is made here :
features/user.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import {apiCall} from "./utils";
export const fetchUserInfo = createAsyncThunk(
'user/info',
async (thunkAPI) => {
const res = await apiCall('https://my.api/userinfo').json();
return res;
});
export const userSlice = createSlice({
name: 'user',
initialState: { info: '' },
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUserInfo.fulfilled, (state, action) => {
state.info = action.payload;
})
},
});
export default userSlice.reducer;
What I would like to do is replace this slice by something like that :
Errored Version :
api/user.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
const rawBaseQuery = (baseUrl) => fetchBaseQuery({
baseUrl,
prepareHeaders: (headers, {getState}) => {
headers.set('Authorization', '*******');
return headers
}
});
export const baseQuery = async (args, api, extraOptions) => {
const baseUrl = api.getState().api.root; // 'https://my.api'
return rawBaseQuery(baseUrl)(args, api, extraOptions);
};
export const userApi = createApi({
reducerPath: 'user',
baseQuery: baseQuery,
endpoints: (builder) => ({
getUserInfo: builder.query({
query: () => `/userinfo`
}),
}),
});
export const {
useGetUserInfoQuery
} = userApi;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from "react-redux";
import App from './App';
import store from './store';
import {useGetUserInfoQuery} from "./api/user";
store.dispatch(useGetUserInfoQuery());
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('root')
);
But, I can not call useGetUserInfoQuery() in ìndex.js. The following error occurs :
React Hook use query cannot be called at the top level.
I also tried to call useGetUserInfoQuery() without dispatch but the same error occurs.
How should I proceed? Thanks!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
