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

如何在其他组件登录后,无需刷新同步更新AppBar的用户信息

解决AppBar与Profile组件登录状态不同步问题

问题原因:AppBar组件的useEffect仅在组件挂载时执行一次Auth.currentAuthenticatedUser(),登录完成后不会自动重新触发,导致状态无法同步;而Profile组件使用的Authenticator内部已监听登录状态变化,因此能实时更新用户信息。

以下是几种可行的解决方案:

方案一:使用Amplify官方的useAuthenticator钩子(最简方案)

Amplify的@aws-amplify/ui-react包提供了useAuthenticator钩子,可直接获取全局同步的用户状态,无需手动监听事件或管理状态:

import { useAuthenticator } from '@aws-amplify/ui-react';

function AppBar() {
  const { user } = useAuthenticator();
  return <div>AppBar: {user?.username || '未登录'}</div>;
}

function Profile() {
  return <Authenticator>
    {({ user, signOut }) => (
      <>
        <div>Profile: { user.username }</div>
        <button onClick={signOut}>Sign Out</button>
      </>
    )}
  </Authenticator>
}

function App() {
  return (
    <>
      <AppBar />
      <Profile />
    </>
  );
}

方案二:监听Auth事件手动同步状态

通过Amplify Auth提供的事件监听机制,在AppBar中监听signIn和signOut事件,触发用户信息重新获取:

import { useState, useEffect } from 'react';
import { Auth } from 'aws-amplify';

function AppBar() {
  const [user, setUser] = useState<string | null>(null);

  // 封装获取用户信息的方法
  const fetchCurrentUser = async () => {
    try {
      const authUser = await Auth.currentAuthenticatedUser();
      setUser(authUser.username);
    } catch (err) {
      // 用户未登录时重置状态
      setUser(null);
    }
  };

  useEffect(() => {
    // 初始加载用户信息
    fetchCurrentUser();

    // 监听登录事件,触发状态更新
    const signInListener = Auth.listen('signIn', fetchCurrentUser);
    // 监听登出事件,触发状态更新
    const signOutListener = Auth.listen('signOut', fetchCurrentUser);

    // 组件卸载时清除监听
    return () => {
      signInListener();
      signOutListener();
    };
  }, []);

  return <div>AppBar: {user || '未登录'}</div>;
}

// Profile和App组件保持不变

方案三:使用React Context共享全局用户状态

通过创建Auth上下文,将用户状态提升到全局,让所有需要的组件共享同步状态:

1. 创建AuthContext

import { createContext, useContext, useState, useEffect } from 'react';
import { Auth } from 'aws-amplify';

const AuthContext = createContext<{ user: any | null }>({ user: null });

export function AuthProvider({ children }) {
  const [user, setUser] = useState<any | null>(null);

  const fetchUser = async () => {
    try {
      const authUser = await Auth.currentAuthenticatedUser();
      setUser(authUser);
    } catch (err) {
      setUser(null);
    }
  };

  useEffect(() => {
    fetchUser();

    const signInListener = Auth.listen('signIn', fetchUser);
    const signOutListener = Auth.listen('signOut', fetchUser);

    return () => {
      signInListener();
      signOutListener();
    };
  }, []);

  return (
    <AuthContext.Provider value={{ user }}>
      {children}
    </AuthContext.Provider>
  );
}

// 自定义钩子简化上下文调用
export function useAuth() {
  return useContext(AuthContext);
}

2. 在App组件中包裹Provider

import { AuthProvider } from './AuthContext';

function App() {
  return (
    <AuthProvider>
      <AppBar />
      <Profile />
    </AuthProvider>
  );
}

3. 修改AppBar和Profile组件使用Context

// AppBar组件
import { useAuth } from './AuthContext';

function AppBar() {
  const { user } = useAuth();
  return <div>AppBar: {user?.username || '未登录'}</div>;
}

// Profile组件(可选,也可继续使用Authenticator)
import { useAuth } from './AuthContext';
import { useAuthenticator } from '@aws-amplify/ui-react';

function Profile() {
  const { user } = useAuth();
  const { signOut } = useAuthenticator();

  if (!user) {
    return <Authenticator />;
  }

  return (
    <>
      <div>Profile: {user.username}</div>
      <button onClick={signOut}>Sign Out</button>
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:35:30