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

父组件调用子组件异步登录验证函数失效问题求助

问题分析与解决方案

核心问题排查

  • 变量名冲突:你导入了user store,但又在isLogged函数里声明了同名局部变量const user = supabase.auth.user();,导致后续user.set(session.user)是对普通用户对象调用store的set方法,完全无效,且user.id的取值也会出错。
  • 指令使用不当:用use:isLogged指令绑定到<p>元素执行登录检查,指令依赖元素挂载触发,当组件作为子组件引入时,元素挂载时机可能和组件初始化不同步,导致逻辑不执行或异常。
  • 重复监听内存泄漏:每次组件挂载都注册supabase.auth.onAuthStateChange监听,未在组件卸载时取消,会造成重复监听和内存泄漏。
  • 逻辑反向:查询到用户数据(data存在)时跳转到登录页,这与登录状态检查的预期逻辑相反,应该是未查询到用户或出错时才跳转。

修正后的代码

<script>
import { goto } from '$app/navigation';
import { onMount, onDestroy } from 'svelte';
import { user } from '../sessionStore';
import { supabase } from '../supabaseClient';

let loading = false;
let authListener = null;

async function checkAuthStatus() {
    try {
        loading = true;
        // 避免变量名冲突,改用currentUser指代当前用户对象
        const currentUser = supabase.auth.user();
        if (!currentUser) {
            goto('/signin');
            return;
        }

        // 更新全局user store
        user.set(currentUser);

        let { data, error, status } = await supabase
            .from('users')
            .select('*')
            .eq('id', currentUser.id)
            .single();

        if (error && status !== 406) throw error;

        // 逻辑修正:仅当数据库中无用户数据时跳转登录页
        if (!data) {
            goto('/signin');
        }
    } catch (error) {
        console.error('登录状态检查失败:', error);
        goto('/signin');
    } finally {
        loading = false;
    }
}

onMount(async () => {
    // 组件挂载时立即执行登录状态检查
    await checkAuthStatus();

    // 注册auth状态变化监听,保存监听函数用于卸载时取消
    authListener = supabase.auth.onAuthStateChange((_, session) => {
        if (session?.user) {
            user.set(session.user);
        } else {
            goto('/signin');
        }
    });
});

onDestroy(() => {
    // 组件卸载时取消监听,防止内存泄漏
    if (authListener) {
        authListener.unsubscribe();
    }
});
</script>

{#if loading}
<p>加载中...</p>
{/if}

关键修正说明

  • 变量名区分:将局部用户变量改为currentUser,避免覆盖导入的user store,确保store的set方法能正确调用。
  • 改用生命周期钩子:用onMount执行初始化登录检查,确保组件挂载时就触发逻辑,不受元素挂载的影响,适配子组件场景。
  • 清理监听:用onDestroy取消onAuthStateChange的监听,防止重复监听和内存泄漏。
  • 修正逻辑方向:只有当用户不存在或数据库查询不到用户数据时,才跳转到登录页,符合登录状态检查的预期。
  • 加载状态提示:添加加载状态的UI反馈,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:15:35