You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

刷新/course页面时useEffect未触发,登录按钮卡在加载状态

问题原因与解决方案

核心问题

最关键的问题是**SiteHeader组件未声明为客户端组件**,同时useEffect缺少依赖数组导致潜在逻辑异常。

在Next.js中,使用useState、useEffect、useRouter这类客户端钩子,或者createClientComponentClient这类客户端专属Supabase API的组件,必须添加'use client'指令——否则客户端钩子完全不会执行,这就是刷新/course页面时useEffect未调用、按钮卡在“Loading”的根本原因。

另外,/course页面是服务器组件,会在服务器端完成会话校验与跳转,但未声明为客户端组件的SiteHeader在客户端 hydration 阶段无法激活钩子逻辑,进一步加剧了问题。

修复步骤

1. 修复SiteHeader组件

在组件最顶部添加客户端组件声明,并修正useEffect的依赖数组:

'use client' // 必须添加这一行,标记为客户端组件
import { useState, useEffect } from 'react'
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'
import { useRouter } from 'next/navigation'
// 导入其他必要组件...

export function SiteHeader() {
  const supabase = createClientComponentClient<Database>()
  const router = useRouter()
  const [usersession, setUser] = useState(false)
  const [loading, setLoading] = useState(true)

  const handleSignOut = async () => {
    if (usersession) {
      const { error } = await supabase.auth.signOut()
      if (!error) {
        setUser(false)
        router.refresh()
      } else {
        console.error("Error signing out:", error)
      }
    } else {
      console.log("user is not logged in")
      router.push("/authentication")
    }
  }

  // 添加空依赖数组,确保仅在组件挂载功用\_重林明确赋值的特殊逻辑Book批量宝 construct
  useEffect(() => {
    console.log("useEffect is called")
    const fetchUser = async () => {
      try {
        const { data: { session } } = await supabase.auth.getSession()
        setUser(!!session?.user) // 简化状态赋值逻辑
      } catch (error) {
        console.error("Error fetching session:", error)
        setUser(false)
      } finally {
        setLoading(false) 
      }
    }

    fetchUser()
  }, []) // 空依赖数组:仅组件挂载时执行一次


  return (
    <header className="sticky top-0 z-40 w-full border-b bg-background">
      <div className="container flex items-center h-16 space-x-4 sm:justify-between sm:space-x-0">
        <MainNav items={siteConfig.mainNav} />
        <div className="flex items-center justify-end flex-1 space-x-4">
          <nav className="flex items-center space-x-1">
            <Button
              onClick={handleSignOut} // 无需额外async包裹,函数本身已是async
            >
              {loading ? "Loading..." : usersession ? "Sign Out" : "Sign In"}
            </Button>
          </nav>
        </div>
      </div>
    </header>
  )
}

2. 优化CourseHomePage会话处理(可选)

将会话校验逻辑提前,避免无会话时执行不必要的数据库查询:

import { getSession } from '@supabase/auth-helpers-nextjs'
import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'
import { redirect } from 'next/navigation'

const CourseHomePage = async () => {
  const session = await getSession()

  // 提前校验会话,无会话直接跳转
  if (!session) {
    return redirect("/authentication")
  }

  // 会话存在时再执行数据库查询
  const supabase = createClientComponentClient<Database>()
  const { data: supabase_data, error } = await supabase
    .from("payment")
    .select()
    .eq("created_by", session.user.id)
    .eq("is_success", true)

  if (error) {
    console.error("Error fetching payment data:", error)
  }

  // 渲染页面内容...
}

内容的提问来源于stack exchange,提问作者Cai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:53:13