-
I've started playing around with RTK Query and i've managed to get most parts working, but when I setup a simple test query to use in a component, using the generated hook the 'data' is always undefined, isLoading is always true and isError, isSuccess are always false. I'm using : I've created a custom baseQuery which returns either { data } or { error }, which basically just massages the api result into the format I want and handles re-auth and ui notifications based on the result: const baseQuery = fetchBaseQuery({
baseUrl: '<base>/api',
prepareHeaders: (headers, api) => {
const token = selectAccessToken(api.getState());
if (token) {
headers.set("Authorization", '<token>');
}
headers.set('Content-Type', 'application/json;charset-UTF-8');
headers.set('Accept', 'application/json');
headers.set('Origin', origin);
return headers;
},
}); const apiBaseQuery: BaseQueryFn<
string | FetchArgs,
unknown,
ProblemDetails,
ApiExtraOptions,
FetchBaseQueryMeta
> = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, apiOptions);
// re-auth - will re-auth on a 401 and re-call the failed query or just returns the original 'result'
result = await handleReAuth(result, args, api, apiOptions);
// success - handle T result and notifications (just extracts the value from the result (or undefined if there is an error) and shows notifications)
const maybeApiResult = handleSuccess(result, api);
// failure - handle problem details and notifications (just extracts the error value from the result (or undefined if no error) and shows notifications)
const maybeProblemDetails = handleError(result, api, apiOptions);
return {
...result,
data: maybeApiResult,
error: maybeProblemDetails,
};
} I've defined the createApi like so export const apiSlice = createApi({
baseQuery: apiBaseQuery,
tagTypes: ['test', 'user'],
endpoints: () => ({}),
}); Included the reducer and middleware const reducers = {
auth: authReducer,
notifications: notificationsReducer,
[apiSlice.reducerPath]: apiSlice.reducer,
};
export const store = configureStore({
reducer,
devTools: isDev(),
preloadedState: rehydratedState,
middleware: getDefaultMiddleware => getDefaultMiddleware()
.concat(apiSlice.middleware)
.prepend(crashReporterMiddleware)
.concat(loggerMiddleware)
}); Then i have defined a test query as follows: const testApi = apiSlice.injectEndpoints({
endpoints: (builder) => ({
testGet: builder.query<string, number>({
query: (num: number) => ({
url: 'v1/test/TestGet',
params: { value: new String(num).substring(0,6) },
providesTags: ['test'],
}),
}),
})
});
export const {
useTestGetQuery,
} = testApi; Then call its generated hook in a component: const {
data,
error,
isLoading,
isFetching ,
isError,
isSuccess
} = useTestGetQuery(new Date().valueOf());
console.log(data, error, isLoading, isError, isSuccess);
return (<div>
<>
{ isLoading === true ? 'loading' : 'not loading' }<br />
{ isFetching === true ? 'fetching' : 'not fetching' }<br />
data: { data }<br />
currentData: { currentData }<br />
<Button onClick={ () => refetch() }>Refresh</Button>
</>
</div>); From the logging I have in place i can see the query fires off correctly and returns a 200 result with the correct data from the api endpoint. Looking in the store i can see the request was fulfilled with the correct payload; but the component does not re-render so data is always undefined and the the status bools never change. I'm not sure where to go from here to debug why the component is not updating. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This will fire a new query on each render because every render you provide a new timestamp as argument. As a result it will probably never finish. |
Beta Was this translation helpful? Give feedback.
This will fire a new query on each render because every render you provide a new timestamp as argument. As a result it will probably never finish.