I have this Zustand store to store authenticaction information about logged in user.
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("/")
}
});
This is HTTPApiClient
that for communication with REST API uses Axios, example of GET method (the rest omitted for brevity).
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;
}
And this piece of code is executed in React component when user is logging out.
const doLogoutSelector = (state: any) => state.doLogout;
const doLogout = useAuthStore(doLogoutSelector);
const signout = () => {
doLogout()
return <Navigate replace to="/"/>
}
I would like to logout user when HTTPApiClient
gets 401 Unathorized
status code from the backend. I am able to recognize the 401 code in client but I don't know how to call logout hook.
Q: How to call React the hook outside of React component?
The answer is simple:
useAuthStore.getState().doLogout()
E.g. my error-interceptor looks like:
...
if (error instanceof AxiosError && response?.status === 401) {
useAuth.getState().logout()
}
...
useAuth.ts
export const useAuth = create((set, get) => ({
logout: async () => {
...
},
...
}))