在 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
內的條件分支。新程式碼將如下所示: