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

从登录页导航至主页时无法获取Supabase会话状态的问题

React + Supabase 会话丢失问题修复

核心问题分析

  1. 原始AuthContext异步处理错误:supabase.auth.getSession()是异步方法,直接赋值会得到Promise而非实际会话数据,导致初始user被设为null;同时onAuthStateChange的回调参数格式错误,未正确接收event和session。
  2. Login组件冗余刷新:登录后调用window.location.reload()会重置整个应用状态,导致AuthContext中存储的会话数据丢失。
  3. 异步版本AuthContext订阅错误:onAuthStateChange是订阅函数,无需await包裹;未初始化loading状态,导致子组件提前渲染;未主动获取初始会话,仅依赖状态变化事件,页面加载时无法同步已有会话。

修复后的代码

1. 修正AuthContext.js

import React, { useContext, useState, useEffect } from "react";
import { supabase } from "../supabaseClient";

const AuthContext = React.createContext();

export function useAuth() {
  return useContext(AuthContext);
}

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // 主动获取初始会话
    const fetchInitialSession = async () => {
      const { data: { session }, error } = await supabase.auth.getSession();
      if (!error && session) {
        setUser(session.user);
      }
      setLoading(false);
    };

    fetchInitialSession();

    // 订阅Auth状态变化
    const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
      setUser(session?.user ?? null);
      setLoading(false);
    });

    // 组件卸载时取消订阅
    return () => subscription?.unsubscribe();
  }, []);

  const value = {
    signUp: (data) => supabase.auth.signUp(data),
    signIn: (data) => supabase.auth.signInWithPassword(data),
    signOut: () => supabase.auth.signOut(),
    user,
  };
  
  return (
    <AuthContext.Provider value={value}>
      {!loading && children}
    </AuthContext.Provider>
  );
}

2. 修正Login.js(移除冗余刷新)

import "./Auth.css";
import {Link, useNavigate} from 'react-router-dom';
import {useRef, useState} from 'react';
import {useAuth} from '../../../contexts/AuthContext';

function Login() {
  const emailRef = useRef();
  const passwordRef = useRef();

  const [error,setError] = useState(null);
  const [message, setMessage] = useState('');

  const {signIn } = useAuth();
  let navigate = useNavigate();

  async function handleSubmit(e) {
    e.preventDefault();
    
    const email = emailRef.current.value;
    const password = passwordRef.current.value;

    const {data, error} = await signIn({email, password})

    if (error) {
      setError(error);
      setMessage("Error: " + error.message)
      return
    }
    // 移除window.location.reload(),直接导航即可
    navigate("/")
  }

  return (
    <div className="text-center div">
      <form className="form-signin" onSubmit={handleSubmit}>
        <h1 className="h3 mb-3 font-weight-normal">Please sign in</h1>
        <label htmlFor="inputEmail" className="sr-only">
          Email address
        </label>
        <input
          ref={emailRef}
          type="email"
          id="inputEmail"
          className="form-control"
          placeholder="Email address"
          required
        />
        <label htmlFor="inputPassword" className="sr-only">
          Password
        </label>
        <input
          ref={passwordRef}
          type="password"
          id="inputPassword"
          className="form-control"
          placeholder="Password"
          required
        />
        <div className="checkbox mb-3">
          <label>
            <input type="checkbox" defaultValue="remember-me" /> Remember me
          </label>
        </div>
        <button className="btn btn-lg btn-primary btn-block" type="submit">
          Sign in
        </button>
        <Link to="/signup"><a>Sign Up</a></Link>
      </form>
      {message? <p>{message}</p> : ""}
    </div>
  );
}

export default Login;

关键修复点说明

  • 初始会话获取:通过异步函数fetchInitialSession主动获取登录状态,确保页面加载时能同步已有会话。
  • 正确处理Auth状态订阅:onAuthStateChange回调接收完整的event和session参数,状态变化时及时更新user。
  • 移除冗余刷新:登录后直接导航,避免页面重置导致状态丢失。
  • 初始化loading状态:设置loading初始值为true,确保会话加载完成后再渲染子组件,避免初始user为null的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:24:29