【发布时间】:2022-01-13 15:55:53
【问题描述】:
试图找出实现以下目标的最佳方法:
- API 通过
createApi - 通过
createSlice验证切片 - API 收到 401 时清除 redux 身份验证状态。
前两个没问题!但问题是当我需要向 API 添加拦截器时(无效的身份验证 - 清除本地身份验证状态):
// api.ts
import authSlice from './authSlice';
const baseQueryWithReauth: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (
args,
api,
extraOptions
) => {
const result = await baseQuery(args, api, extraOptions)
if (result.error?.status === 401) {
api.dispatch(authSlice.actions.clearAuth())
}
return result
}
export const api = createApi({
reducerPath: API_REDUCER_KEY,
baseQuery: baseQueryWithReauth,
endpoints: () => ({}),
})
// authService.ts
import { User } from '../../models/User'
import { api } from '../api'
export const API_REDUCER_KEY = 'api'
interface AuthResponse {
user: User
jwt: string
}
interface LoginData {
email: string
password: string
}
export const authApi = api.injectEndpoints({
endpoints: (builder) => ({
login: builder.mutation<AuthResponse, LoginData>({
query: (body) => {
return {
url: 'login',
method: 'POST',
body,
}
},
}),
}),
})
export const { useLoginMutation } = authApi
这会导致循环依赖 - 因为身份验证切片需要为身份验证功能(登录、注销等)调用 API:
// authSlice.ts
import { api } from './api';
...
export const loginLocal = createAsyncThunk<
Pick<AuthState, 'user' | 'accessToken'>,
{
email: string
password: string
}
>('auth/login', async ({ email, password }, { dispatch }) => {
const response = await dispatch(
authApi.endpoints.login.initiate({
email,
password,
})
)
if ('error' in response) {
if ('status' in response.error) {
throw new Error(response.error.data as string)
}
throw new Error(response.error.message)
}
const { data } = response
const { jwt: accessToken, user } = data
return { user, accessToken }
})
循环依赖如下:authSlice -> authService -> api -> authSlice
有没有办法解决这个问题 - 或者我可以使用更好/不同的模式?
【问题讨论】:
-
如果你把
baseQueryWithReauth移到一个单独的文件里会不会解决问题?比你不必在你的api.ts中导入authSlice -
另外,为什么
loginLocal写成createAsyncThunk?这感觉就像会进入 API 切片一样。 -
@TheWuif - 我相信这仍然是一个循环依赖,只是在链中有一个额外的链接:authSlice -> authService -> api -> baseQueryWithReauth -> authSlice
-
@markerikson - 我也在该函数中应用一些与问题无关的异步逻辑:)
标签: reactjs redux redux-toolkit rtk-query