问题
Creating an app which allows you to sign up and sign in user in the database. After sign up / sign in process the app moves you to the content.
Code for authorization process:
const Auth = ({ handleSetAuthorized }) => {
const { refetch } = useQuery(CURRENT_USER)
const { error } = useSelector(({ error }) => error)
const history = useHistory()
const dispatch = useDispatch()
const [signup] = useMutation(SIGN_UP, {
onCompleted: async (data) => {
const token = data.signup
localStorage.setItem("token", token)
await refetch()
handleSetAuthorized()
history.push("/pages/edituser")
},
onError: error => dispatch(getError(error))
})
const [login] = useMutation(SIGN_IN, {
onCompleted: async (data) => {
const token = data.login.token
localStorage.setItem("token", token)
await refetch()
handleSetAuthorized()
history.push("/pages/process")
},
onError: error => dispatch(getError(error))
})
const signUp = (values) => {
signup({
variables: {
firstName: values.firstName,
secondName: values.secondName,
email: values.email,
password: values.password,
}
})
}
const signIn = (values) =>{
login({
variables: {
email: values.email,
password: values.password,
}
})
}
const removeError = () => {
dispatch(cleanError())
}
return (
<>
<div className="auth">
<img
className="auth__logo"
src={logo}
alt="logo"
/>
<div className="auth__content">
<Switch>
<Route path="/auth/signin" >
<SignIn onSubmit={signIn} removeError={removeError}/>
</Route>
<Route path="/auth/signup">
<SignUp onSubmit={signUp} removeError={removeError}/>
</Route>
</Switch>
{error &&
<ErrorMessage className="mistake">
{error.message}
</ErrorMessage>
}
</div>
</div>
</>
)
}
export default Auth
As you can see after mutation is completed, I need to refetch my CURRENT_USER query to understand who is current user and to move user to the content. I do that here:
const { refetch } = useQuery(CURRENT_USER)
const [signup] = useMutation(SIGN_UP, {
onCompleted: async (data) => {
const token = data.signup
localStorage.setItem("token", token)
await refetch() // <- HERE!
handleSetAuthorized()
history.push("/pages/edituser")
},
onError: error => dispatch(getError(error))
})
Code works but the problem is I don't want to refetch query like that: import CURRENT_USER query itself, get refetch function from useQuery hook and use it inside onCompleted option of mutation.
ApolloClient provides next:
I can put
refetchQueries
option inside useMutation hook to refetch my CURRENT_USER query like that:const [signup] = useMutation(SIGN_UP, { refetchQueries: [{query: CURRENT_USER }], // <- HERE! onCompleted: (data) => { const token = data.signup localStorage.setItem("token", token) handleSetAuthorized() history.push("/pages/edituser") }, onError: error => dispatch(getError(error))
})
That approach doesn't work because refetchQueries option updates CURRENT_USER query before I get and put token from mutation result in localStorage. So user is not moved to content because CURRENT_USER query result is empty and app shows user a mistake.
I can use 'refetch-queries' npm package. It provides the option to refetch Apollo queries anywhere by name and partial variables. Perfect for my case and look like that:
const [signup] = useMutation(SIGN_UP, { onCompleted: (data) => { const token = data.signup localStorage.setItem("token", token) refetchQueries: [{query: CURRENT_USER }], // <- HERE! handleSetAuthorized() history.push("/pages/edituser") }, onError: error => dispatch(getError(error))
})
So here I use that option inside onCompleted option and after putting token in localStorage. Seems perfect in my case but doesn't work. I have no idea why, it throws the same mistake which shows that CURRENT_USER query result is empty. Maybe package is not supported.
My wish is to refetch CURRENT_USER query after pushing user to the content and before content (Pages component) initialization. But how to do that using useEffect hook inside content (Pages component) and without componentWillMount method.
And what is the best practice for refetching queries after mutation in my situation?
来源:https://stackoverflow.com/questions/65038096/proper-way-of-refetching-queries-after-mutation-in-react-apolloclient-project