I want to fetch data from my backend, change the 'isLoggedIn' state accordingly and therefore render a component conditionally. I just can't get my around it on how to structure it in a way that the component does not render twice.
First in my AuthForm component, there is a login function. It sets a httpOnly cookie for refreshing the JWT token, and and a JWT token directly on the headers.
const login = async () => {
try {
const response = await axios.post(props.baseUrl + "/auth/login", {
email,
password,
})
axios.defaults.headers.common[
"Authorization"
] = `Bearer ${response.data.token}`
dispatch(toggleLogin(true))
} catch ({ response }) {
console.log(response)
}
}
Since I want to display the Game UI instead of the AuthForm, I'm dispatching the toggleLogin action.
In the main component, i have a refreshToken function, that checks if the client got a httpOnly cookie and returns a new JWT if it is valid. So that the user is still logged in on a page refresh.
const Tamagotchi = () => {
const isLoggedIn = useSelector((state) => state.isLoggedIn)
const dispatch = useDispatch()
const refreshToken = async () => {
try {
const response = await axios.get(baseUrl + "/auth/refresh-token")
axios.defaults.headers.common[
"Authorization"
] = `Bearer ${response.data.token}`
dispatch(toggleLogin(true))
setTimeout(() => {
refreshToken()
}, response.data.expiresIn * 1000 - 500)
} catch ({ response }) {
if (response.status !== 201) {
dispatch(toggleLogin(false))
console.log("Not authorized")
}
}
}
useEffect(() => {
refreshToken()
})
return (
<TamagotchiWrapper>
<TamagotchiView>
{isLoggedIn ? <TamagotchiUI /> : <AuthForm />}
</TamagotchiView>
</TamagotchiWrapper>
)
}
If the user is logging in, or is refreshing the page, the Tamagotchi component gets rendered twice. The state gets changed because isLoggedIn changes and therefore it renders again and calling the useEffect hook again.
How to go about this?
Thanks in advance.