在 useEffect 内部,刷新页面时会触发两个条件分支
P粉798343415
2023-09-03 14:09:00
<p>这是React组件中的<code>useEffect</code>代码。</p>
<pre class="brush:js;toolbar:false;"> import { useSession } from '@supabase/auth-helpers-react'
const session = useSession()
useEffect(() => {
if (session) {
console.debug('stay in page')
} else {
console.debug('goto login')
router.push('/login').then(
() => {
console.debug('goto login done')
}
)
}
}, [session, router])
</pre>
<p>它使用supabase来管理身份验证(会话)。</p>
<p>刷新页面时有一个非常奇怪的问题(通过路由器登录、注销重定向完全没有问题,只有刷新页面时才出现。),两个分支都会到达,所以在js控制台中,我们可以看到来自两个分支的日志条件分支。</p>
<p><code>“留在页面”</code> 和<code>转到登录</code>/<code>转到登录完成</code>。</p>
<blockquote>
<p>我认为这是由于刷新后<code>会话</code>发生了变化。第一次未定义,触发第二个分支<code>router.push</code>,当找到会话时,立即触发第一个分支<code>停留在页面</code>。</p>
</blockquote>
<p>有什么建议可以绕过它吗?或者在 React/NextJS 中有任何<strong>处理页面刷新的良好实践</strong>?或者有人以前遇到过类似或相同的问题吗?</p>
在您的代码中,只要会话或路由器的值发生更改(useEffect 的第二个参数),就会执行 useEffect。因此,if 和 else 都不会在 useEffect 的同一次运行中执行,尽管是在可能快速连续执行的两次不同运行中执行。
这是实现您所追求的目标的一种方法。
示例实现:
终于,我找到了根本原因。
它来自 supabase auth helper,它是一个异步函数,它不包含是否正在加载或错误的状态,这意味着它在开始(这意味着它正在加载)。
解决这个问题的简单方法是直接使用
useSessionContext
。session
仍将以异步方式获取,但可以通过同步方式获取isLoading
和error
状态来解决此问题,并且它们可用于useEffect
内的条件分支。新代码将如下所示: