在 useEffect 内部,刷新页面时会触发两个条件分支
P粉798343415
P粉798343415 2023-09-03 14:09:00
[React讨论组]

这是React组件中的useEffect代码。

  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])

它使用supabase来管理身份验证(会话)。

刷新页面时有一个非常奇怪的问题(通过路由器登录、注销重定向完全没有问题,只有刷新页面时才出现。),两个分支都会到达,所以在js控制台中,我们可以看到来自两个分支的日志条件分支。

“留在页面”转到登录/转到登录完成

我认为这是由于刷新后会话发生了变化。第一次未定义,触发第二个分支router.push,当找到会话时,立即触发第一个分支停留在页面

有什么建议可以绕过它吗?或者在 React/NextJS 中有任何处理页面刷新的良好实践?或者有人以前遇到过类似或相同的问题吗?

P粉798343415
P粉798343415

全部回复(2)
P粉276876663

在您的代码中,只要会话或路由器的值发生更改(useEffect 的第二个参数),就会执行 useEffect。因此,if 和 else 都不会在 useEffect 的同一次运行中执行,尽管是在可能快速连续执行的两次不同运行中执行。

这是实现您所追求的目标的一种方法。

  1. 使用 useState 创建和管理变量的状态
  2. 在 useEffect 中,通过应用逻辑检查会话来设置(或不设置)状态
  3. 在返回中呈现当前页面或显示登录页面。

示例实现:

const App = (props) => {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  
  useEffect(()=>{
    //apply the logic and set the state
    if(logic) setIsLoggedIn(true);
  },[]) 
  
  return  {isLoggedIn ? <ActiveApp /> : <Login />}

}
P粉035600555

终于,我找到了根本原因。

它来自 supabase auth helper,它是一个异步函数,它不包含是否正在加载或错误的状态,这意味着它在开始(这意味着它正在加载)。

解决这个问题的简单方法是直接使用useSessionContextsession 仍将以异步方式获取,但可以通过同步方式获取 isLoadingerror 状态来解决此问题,并且它们可用于 useEffect 内的条件分支。

新代码将如下所示:

  import { useSessionContext } from '@supabase/auth-helpers-react'
  const {isLoading, session} = useSessionContext()
  useEffect(() => {

    if (isLoading) {
      console.debug('show loading page')
    }
    else if (session) {
      console.debug('stay in page')
    } 
    else {
      console.debug('goto login')
      router.push('/login').then(
        () => {
          console.debug('goto login done')
        }
      )
    }
  }, [session, isLoading, router])

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号