Javascript 在等待道具时替换useEffect中的setTimeout
我正在寻找一个更好的解决方案,使用Javascript 在等待道具时替换useEffect中的setTimeout,javascript,reactjs,Javascript,Reactjs,我正在寻找一个更好的解决方案,使用setTimeout等待props使用useffect()钩子。目前我已经按计划工作了 const sessionCookie = getCookie('_session'); const { verifiedEmail } = props.credentials; const [loading, setLoading] = useState(true); useEffect(() => { const timeoutLoading = setTime
setTimeout
等待props
使用useffect()
钩子。目前我已经按计划工作了
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]);
而props.credentials
的初始状态是{}
,等待服务器的响应
为verifiedEmail
和sessionCookie
提供值,依赖函数getCookie
返回cookie是否存在以及值
虽然这样做有效,但并不理想。一个例子是,在某些用户情况下,2s的时间不够,在其他情况下,当道具已经可用时,它会让用户等待
我的问题是,如何创建一个承诺
或使用异步/等待
来实现相同的效果,而不存在使用设置超时
的风险
注意:props.credentials
在render
上不可用,并且在包含verifiedEmail
之前总是返回一个空的对象。在某些情况下,sessionokie
可能在render
上也不可用,但在props之前也可用。凭据具有verifiedEmail
。如果sessionokie
存在,verifiedEmail
将在之后不久发出
理想情况下,我最好围绕getCookie
创建一个promise
,然后在识别verifiedEmail
存在之前确保\u会话可用。有什么想法吗
getCookie()
如下所示
const getCookie = (name: string) => {
const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : null;
};
更新
你能添加一个名为hasAuthenticated的新道具吗。当您的请求挂起时,这可能是错误的。请求完成后,将其设置为true并在此时应用您的逻辑,就像isLoading
这样就不需要计时器了
以前的
您可以使用两个useffects
来尝试类似的方法。第一个将处理会话cookie的设置,第二个将触发窗口更改
不过,我不确定您的getCookie
函数是如何工作的
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]);
看起来您缺少useEffect中的sessionCookie依赖项,因为您知道当cookie发生更改时,它将运行该效果,并且您可以根据cookie状态维护一个不基于setTimeout的加载状态。我不知道这是否是正确的建议,但您能试一试吗props.credentials
在开始时是{}
,但经过一段时间(cookie刷新等),它的值被设置,即props
变量被更改,这意味着发生了重新渲染。您能否使用props.credentials
作为依赖项数组创建useffect
?看看运气如何?@SamridhTuladhar。谢谢你的建议。不幸的是,这是行不通的。由于props.credentials
在sessionCookie
可用之前首先呈现为{}
,因此,该条件假设没有cookie,并且用户被重定向为cookie。@PunithK。要实现这一点,需要父级传递sessionokie
,父级没有。当您使用setTimeout时,这是否意味着凭据将由ajax获取,因此此道具在第一次渲染时不可用?谢谢Todd。我将在问题中添加getCookie
。不幸的是,wait对getCookie
没有任何影响。为什么getCookie有时没有值,需要您等待?您是否在项目中的其他地方设置cookie?您需要通知组件cookie是否以某种形式设置。我猜您正在尝试区分“尚未”验证和未验证。是的,cookie是在用户到达此页面时添加的。但是,上面的代码在顶层包装页面,这意味着在呈现时,sessionCookie不可用。这样做的原因会使问题复杂化。我可以通过删除getCookie并只侦听凭据来解决这个问题,但为了安全起见,验证cookie和凭据更为理想。确切地说,“还没有”和“还没有”正是我需要实现的。你能添加一个名为hasAuthenticated
或类似的新道具吗。当您的请求挂起时,这可能是错误的。请求完成后,将其设置为true,并在此时应用您的逻辑,就像isLoading
。谢谢Todd。这就是我最终要做的。我有一个名为authenticated
的对象,它最初为空。如果会话cookie可用且凭据object.key.length大于1,则它们在authenticated
对象中显示为布尔值。如果你想将你的问题更新为你在上面的评论,我很乐意接受你的回答。再次感谢您抽出时间。