如何在 React 组件之外调用 Zustand / React hook?

Art*_*gon 13 javascript reactjs axios zustand

我有这个 Zustand 存储来存储有关登录用户的身份验证信息。

const authStore = (set: any) => ({
    ...initialState,
    doLogin: async (user: TLoggedInRequest) => {
        try {
            set(() => ({status: "pending"}))
            const result = await loginService.login(user)
            set(() => ({
                status: "resolved",
                user: result?.data.user,
                error: null
            }))
        } catch (error) {
            console.log("rejected error", error)
            set((state: any) => ({status: "rejected", error}))
        }
    },
    doLogout: async () => {
        await loginService.logout()
        set(() => initialState)
        history.push("/")
    }
});
Run Code Online (Sandbox Code Playgroud)

这是HTTPApiClient使用 Axios 与 REST API 进行通信的 GET 方法的示例(为了简洁,其余部分省略)。

async get<TResponse>(path: string): Promise<TResponse> {
    try {
        const response = await this.instance.get<TResponse>(path);
        return response.data;
    } catch (error: any) {
        handleServiceError(error);
    }
    return {} as TResponse;
}
Run Code Online (Sandbox Code Playgroud)

当用户注销时,这段代码会在 React 组件中执行。

const doLogoutSelector = (state: any) => state.doLogout;
const doLogout = useAuthStore(doLogoutSelector);

const signout = () => {
        doLogout()
        return <Navigate replace to="/"/>
}
Run Code Online (Sandbox Code Playgroud)

我想在从后端HTTPApiClient获取状态代码时注销用户。401 Unathorized我能够识别客户端中的 401 代码,但我不知道如何调用注销挂钩。

Q:如何在React组件之外调用React钩子?

mle*_*ter 36

答案很简单:

useAuthStore.getState().doLogout()
Run Code Online (Sandbox Code Playgroud)

例如我的错误拦截器看起来像:

...
if (error instanceof AxiosError && response?.status === 401) {
  useAuth.getState().logout()
}
...
Run Code Online (Sandbox Code Playgroud)

useAuth.ts

export const useAuth = create((set, get) => ({
  logout: async () => {
    ...
  },
  ...
}))
Run Code Online (Sandbox Code Playgroud)