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

Gatsby中基于useEffect依赖的页面导航异常问题

问题分析

你的问题出在两个核心点:

  1. 初始状态触发过早跳转:Context初始化时user默认是null,首页组件挂载后,useEffect会立刻执行(依赖的user是初始null),直接触发跳转到登录页。后续user更新为用户对象时,首页组件已经因为跳转被卸载,无法再执行跳转逻辑。
  2. 用户状态捕获不完整:你只在Context挂载时调用了一次auth.currentUser(),但GoTrue的currentUser()可能在初始化阶段因为Cookie未完成读取而返回null,之后内部完成验证后才会拿到真实用户数据,此时你的代码没有监听这个变化,导致状态更新不及时。
修复方案

1. 完善Context的用户状态监听

修改context.js,添加GoTrue的onAuthStateChange事件监听,实时捕获用户状态变化,同时处理组件卸载时的清理:

import React, { useEffect, createContext, useState, useMemo } from "react";
import GoTrue from 'gotrue-js';
export const IdentityContext = createContext();

const IdentityContextProvider = (props) => {
  const [user, setUser] = useState(null);
  const [isLoading, setIsLoading] = useState(true); // 添加加载状态,标记用户状态是否确定

  const auth = useMemo(() => {
    return new GoTrue({
      APIUrl: "https://XXXXXX.netlify.app/.netlify/identity",
      audience: "",
      setCookie: true,
    });
  },[]);

  useEffect(() => {
    // 初始化获取用户
    const initialUser = auth.currentUser();
    setUser(initialUser);
    setIsLoading(false);

    // 监听用户状态变化,覆盖登录、登出、Token刷新等场景
    const unsubscribe = auth.onAuthStateChange((event, newUser) => {
      setUser(newUser);
      setIsLoading(false);
    });

    // 组件卸载时取消监听,避免内存泄漏
    return () => unsubscribe();
  },[auth]);

  return (
    <IdentityContext.Provider value={{ auth, user, isLoading }}>
      {props.children}
    </IdentityContext.Provider>
  )
}

export default IdentityContextProvider;

2. 修改首页逻辑,避免过早跳转

修改index.js,等待加载状态结束后再判断跳转,确保用户状态明确后再执行操作:

import { navigate } from 'gatsby-link';
import { useContext, useEffect } from 'react'
import { IdentityContext } from '../contexts/IdentityContext';

export default function HomePage() {
  const { user, isLoading } = useContext(IdentityContext);
  
  useEffect(() => {
    if (isLoading) return; // 加载中不执行跳转,避免初始null状态误触发

    if (user) {
      navigate("/user/home");
      console.log("there's a user");   
    } else {
      navigate("/login");
      console.log("no user");
    }
  }, [user, isLoading]);

  // 加载时返回提示,避免页面空白
  if (isLoading) {
    return <div>加载中...</div>;
  }

  return null;
}
关键说明
  • isLoading状态用于标记用户状态是否已确定,避免在初始null状态下误触发跳转。
  • onAuthStateChange监听能覆盖所有用户状态变更场景,比仅在初始化时调用currentUser()更可靠。
  • 组件卸载时取消事件监听,避免内存泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:16:10