I am using React-query for my React app.
I have useLogin and useLogout hooks which use useQuery:
export const useLogin = (input?: LoginWithEmailPassword) => {
const { data, isLoading, isSuccess, error } = useQuery(
["loginWithEmailPassword"],
() => loginWithEmailPassword(input),
{
enabled: !!input,
}
);
return { data: data?.data, isLoading, isSuccess, error };
};
export const useLogout = (accessToken?: string) => {
const { isSuccess, isLoading, error } = useQuery(
["logout"],
() => logout(accessToken),
{
enabled: !!accessToken,
}
);
return { isSuccess, isLoading, error };
};
In my AuthProvider; where I use the 2 hooks, I also have a login and logout function which will be called when a user clicks login/logout.
Given React-query's declarative approach, I'm also keeping 2 states; loginInput and logoutInput
AuthProvider.tsx
const [loginInput, setLoginInput] = useState<LoginWithEmailPassword>();
const [logoutInput, setLogoutInput] = useState<string | undefined>();
const { data, isSuccess: isLoginSuccess, isLoading } = useLogin(loginInput);
const {...} = useLogout(logoutInput);
const login = (input: LoginWithEmailPassword) => {
setLoginInput(input);
};
const logout = () => {
setLogoutInput(data?.accessToken);
};
This issue I've found is that after the user clicks login and set's the loginInput state; useLogin will run. But useLogin will re-run every time the component re-rerenders because loginInput will still have the state; i.e. if a user clicks logout, useLogin will run again. What would be the best way to resolve this?
Things will be more straightforward if React-query has a useLazyQuery like Apollo.
A hacky approach I can think of is to reset the loginInput state to undefined, like so:
useEffect(()=>{
if(isLoginSuccess && !isLoading && !!data) setLoginInput(undefined)
},[isLoginSuccess])