I have a an async hook, which gets the user useGetUser
function useGetUser() {
const [user, setUser] = useState(false);
useEffect(() => {
async function getUser() {
const session = await Auth.currentSession();
setUser(session);
}
if (!user) {
getUser();
}
}, [user]);
return user;
}
From another hook, I'm calling this hook, and only when I get the user, I want to execute the query:
function useGraphQLQuery() {
const user = useGetUser();
useEffect(() => {
if (user) {
useQuery(`blablabla`, async () =>
request(endpoint, query, undefined, {
authorization: user.getAccessToken().getJwtToken() || '',
})
);
}
}, [user]);
}
This code doesn't work because useQuery
needs to be outside of useEffect
and also because of the condition, but I need to wait for the user to be fetched...
Thank you.
CodePudding user response:
I think you should have a slightly different approach. For example , encapsulate all your routes into a component , let's call it App , in App.js. In App.js you want to use the useEffect hook to check if the user is authentificated or not, something like this:
React.useEffect(() => {
//We refresh the access token every time the page is changed
fetch('http://localhost:1000/refresh_token', {
method: 'POST',
credentials: 'include',
}).then(async x => {
const { accessToken } = await x.json()
// we set the access token
setAccessToken(accessToken)
setLoading(false)
})
}, [])
Then , from the App component, render all your components , just like in index.js. Now you can easily use the useQuery hook in each of your components corresponding to a page .
CodePudding user response:
The useGetUser
hook is a bit strange since it uses a state variable which also is being set by the effect. Since it is really easy to get unwanted effects or even infinite render loops, I would prevent that.
Since it only needs to run once on startup, you can remove the !user
part and also the user
dependency. I can imagine you would like this hook to be updated when the Auth
service receives a session.
function useGetUser() {
const [user, setUser] = useState(false);
useEffect(() => {
async function getUser() {
const session = await Auth.currentSession();
setUser(session);
}
getUser();
}, []);
return user;
}
For the useQuery
hook, you can use the enabled
option to prevent the useQuery
from executing when set to false
. You can also remove the useEffect
since it's already a hook which responds to option changes.
function useGraphQLQuery() {
const user = useGetUser();
useQuery(`blablabla`, async () => request(endpoint, query, undefined, {
authorization: user.getAccessToken().getJwtToken() || '',
}), { enabled: !!user });
}