I am looking for a better solution to using setTimeout
to wait for props
using the useEffect()
hook. Currently I have working as intended
const sessionCookie = getCookie('_session'); const { verifiedEmail } = props.credentials; const [loading, setLoading] = useState(true); useEffect(() => { const timeoutLoading = setTimeout(() => setLoading(false), 2000); if (!loading) { if (sessionCookie) { if (verifiedEmail) { window.location.href = 'https://1.example.com'; } } else { window.location.href = 'https://2.example.com'; } } return () => { clearTimeout(timeoutLoading); }; }, [loading]);
whereas props.credentials
in it’s initial state is {}
, awaiting a response
from the server to give the value for verifiedEmail
and sessionCookie
relies on a function getCookie
to return whether the cookie exists and the value
.
Whilst this works, it’s not ideal. One example would be in some user cases, 2s isn’t enough time, in others it makes the user wait, when the props are already available.
My question is, how can I create a promise
or use async/await
to achieve the same affect without the risk of using setTimeout
.
NOTE: props.credentials
are not available on render
and will always return an empty object
before containing verifiedEmail
. In some cases, the sessionCookie
may not be available on render
too but will also be available before props.credentials
has verifiedEmail
. If sessionCookie
exists, verifiedEmail
will too shortly after.
Ideally I would it best to create a promise
around getCookie
, then ensure the _session
is available before identifying verifiedEmail
exists. Any thoughts?
getCookie()
is as below
const getCookie = (name: string) => { const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); return v ? v[2] : null; };
Advertisement
Answer
Update
Can you add a new prop called hasAuthenticated
or something like that. While your request is pending, this can be false. Once the request is complete, set it to true and apply your logic at that time, just like isLoading
.
That should remove the need for timers.
Previous
You could try something like this using two useEffects
. First one will handle setting your session cookie and the second one will trigger the window change.
I’m not sure how your getCookie
function works though.
const [sessionCookie, setSessionCookie] = useState(null); const [loading, setLoading] = useState(true); const { verifiedEmail } = props.credentials; useEffect(() => { const getSession = async () => { setSessionCookie(await getCookie('_session')); setLoading(false); } getSession(); }, [setSessionCookie, getCookie, setLoading]); useEffect(() => { if (!loading) { if (sessionCookie) { if (verifiedEmail) { window.location.href = 'https://1.example.com'; } } else { window.location.href = 'https://2.example.com'; } } }, [sessionCookie, verifiedEmail, loading]);