Reputation: 971
I've been trying to figure out why tag invalidation is not working and added some logging. The providesTags
in getMe
works fine, but invalidatesTags
in login
is never called. What might be wrong?
I have a redux RTK query API like this:
const baseQuery = fetchBaseQuery({
baseUrl: baseUrl,
prepareHeaders: (headers, { getState }) => {
const token = getState().auth.token
if (token) {
headers.set('authorization', `Bearer ${token}`)
}
return headers
},
})
export const api = createApi({
baseQuery: baseQuery,
tagTypes: ['User'],
endpoints: build => ({
login: build.mutation({
query: code => ({
url: `auth/login/?code=${code}`,
method: 'POST',
}),
invalidatesTags: (result, error, arg) => {
console.log('auth/login', result, error, arg)
return ['User']
},
}),
getMe: build.query({
query: () => 'auth/me',
providesTags: result => {
console.log('auth/me', result)
return ['User']
},
}),
}),
})
export const { useLoginMutation, useGetMeQuery } = api
login
is called on component mount when the page is loaded from a callback like this:
const CallbackComponent = () => {
const location = useLocation()
const [login, { isUninitialized, isLoading, isError, data, error }] = useLoginMutation()
useEffect(() => {
if (isUninitialized) login(getCode(location))
})
...
}
getMe
is used in a component like this:
const Header = () => {
const isAuthenticated = useIsAuthenticated()
const {
data: user,
isError,
error,
} = useGetMeQuery(null, {
skip: !isAuthenticated,
})
if (isError) return <span>{JSON.stringify(error)}</span>
return (
<nav className="header">
{user ? <CharacterList characters={user.characters} /> : null}
{!user || user.characters.length === 0 ? <Login /> : null}
</nav>
)
}
Upvotes: 7
Views: 4641
Reputation: 817
I had an quite similar issue where the getMe request would throw an HTTP 401
response code when called without an valid session token. Turns out, that removing the 401
on server side fixed the issue.
However, this is not an optimal solution, so instead I figured out, the providesTags: ['example']
does provide the tag only on success. To also provide it on failure or some other tag use something like this:
providesTags:(result, error, id)=> (
result
? ['example']
: (error?.status === 401 ? ['UNAUTHORIZED'] : ['UNKNOWN_ERROR'])
)
Although you found your solution to the problem already, this might help someone else running into similar issues.
Upvotes: 0
Reputation: 971
Turns out the issue was not in any of these places. I had not added the api middleware to my store.
export const store = configureStore({
reducer: rootReducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware().concat(api.middleware),
})
docs: https://redux-toolkit.js.org/tutorials/rtk-query#add-the-service-to-your-store
Upvotes: 13