export const useLogin = (loginType) => {
return useQuery({
queryKey: ['login', loginType],
// 'login' is simple function which use axios get method
queryFn: async () => await login(loginType),
});
};
const Login = () => {
const [loginType, setLoginType] = useState('google');
const { data } = useLogin(loginType);
const onClickSocialLogin = (type) => {
setLoginType(type);
// I want to use data
};
return (
<button onClick={() => onClickSocialLogin('google')}>Google Login</button>
<button onClick={() => onClickSocialLogin('github')}>Github Login</button>
)
}
When I click Google Login button, I want to use google login data in onClickSocialLogin function.
When I click Github Login button, I want to use github login data in onClickSocialLogin function.
But When I use data in onClickSocialLogin funtion, this data is old one. How can I fix it??
2
Answers
The issue you’re facing is due to the asynchronous nature of the useQuery hook from React Query. When you call setLoginType(type), it updates the state and triggers a re-render. However, the data fetched by useQuery is not immediately available because the query is asynchronous. Thus, when you try to use data in the onClickSocialLogin function, it still holds the old data from the previous state.
To solve this, you can use the onSuccess callback provided by useQuery. This callback is executed when the query successfully fetches new data. Here’s how you can modify your useLogin hook and Login component:
Modified useLogin Hook
The login component:
This approach ensures that you have the latest data available in the onSuccess callback. You can handle the new data accordingly based on the type of login or any other logic you need. Remember, the onSuccess callback is only triggered after the new data is successfully fetched, so you won’t be dealing with stale data.
Login should be
mutation
. It logs the user in, or creates a token. You don’t want to cache it. It’s also likely a POST request, so it’s a mutation.Mutations don’t have the problem because you can just fire them imperatively: