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

如何在react-router-dom 6.4中将解码后的Google JWT对象传入Layout组件

解决方案

1. 完善 useToken.js 自定义Hook,管理Token与用户信息

先确保useToken Hook不仅存储token,还能自动解码并维护userObject状态,让应用各部分能便捷获取用户信息:

import { useState, useEffect } from 'react';
import jwt_decode from 'jwt-decode';

export default function useToken() {
  // 从localStorage初始化token
  const getToken = () => {
    const tokenString = localStorage.getItem('token');
    const userToken = JSON.parse(tokenString);
    return userToken?.token;
  };

  // 解码token得到用户信息
  const getCurrentUser = () => {
    const token = getToken();
    if (token) {
      try {
        return jwt_decode(token);
      } catch (err) {
        console.error('Token解码失败:', err);
        return null;
      }
    }
    return null;
  };

  const [token, setToken] = useState(getToken());
  const [user, setUser] = useState(getCurrentUser());

  // token变化时自动更新用户信息
  useEffect(() => {
    setUser(getCurrentUser());
  }, [token]);

  const saveToken = (userToken) => {
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken.token);
  };

  const removeToken = () => {
    localStorage.removeItem('token');
    setToken(null);
    setUser(null);
  };

  return {
    setToken: saveToken,
    removeToken,
    token,
    user
  };
}

2. 在 App.js 中配置路由,传递用户信息到Layout

react-router-dom 6.4采用createBrowserRouter+RouterProvider配置路由,将Layout作为父路由的element,直接把user作为props传入,让所有子路由都被Layout包裹并能访问用户信息:

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import useToken from './useToken';
import Layout from './Layout';
import Login from './Login';
import Dashboard from './Dashboard'; // 示例子页面

function App() {
  const { user } = useToken();

  const router = createBrowserRouter([
    {
      path: '/',
      element: <Layout user={user} />, // 传递用户信息到Layout
      children: [
        {
          path: 'dashboard',
          element: <Dashboard />,
        },
        // 其他子路由...
      ],
    },
    {
      path: '/login',
      element: <Login />,
    },
  ]);

  return <RouterProvider router={router} />;
}

export default App;

3. 修改 Layout.js 接收并展示用户名称

在Layout组件中接收user props,在头部区域渲染用户名:

import { Outlet, Link } from 'react-router-dom';

export default function Layout({ user }) {
  return (
    <div className="app-container">
      <header className="header">
        <nav>
          <Link to="/dashboard">首页</Link>
          {user ? (
            <span className="user-name">欢迎, {user.name}</span>
          ) : (
            <Link to="/login">登录</Link>
          )}
        </nav>
      </header>
      <main>
        <Outlet /> {/* 渲染子路由内容 */}
      </main>
    </div>
  );
}

4. 更新 Login.js,登录成功后存储Token

Google登录成功后,调用useToken的setToken方法存储token,触发user状态更新并跳转页面:

import { useNavigate } from 'react-router-dom';
import useToken from './useToken';

export default function Login() {
  const navigate = useNavigate();
  const { setToken } = useToken();

  const handleGoogleLoginSuccess = (response) => {
    // 假设response.id_token是Google返回的JWT
    const token = response.id_token;
    setToken({ token }); // 存储token
    navigate('/dashboard'); // 跳转到首页
  };

  return (
    <div className="login-container">
      {/* Google登录按钮,绑定登录成功回调 */}
      <button onClick={handleGoogleLoginSuccess}>Google登录</button>
    </div>
  );
}

额外优化:用Context全局共享用户信息(可选)

如果应用多个组件都需要访问用户信息,推荐用React Context全局共享,避免逐层传props:

创建 UserContext.js

import { createContext, useContext } from 'react';
import useToken from './useToken';

const UserContext = createContext();

export function UserProvider({ children }) {
  const { user, token, setToken, removeToken } = useToken();
  return (
    <UserContext.Provider value={{ user, token, setToken, removeToken }}>
      {children}
    </UserContext.Provider>
  );
}

export function useUser() {
  return useContext(UserContext);
}

修改 App.js 包裹UserProvider

import { UserProvider } from './UserContext';

function App() {
  return (
    <UserProvider>
      <RouterProvider router={router} />
    </UserProvider>
  );
}

修改 Layout.js 使用useUser Hook

import { useUser } from './UserContext';

export default function Layout() {
  const { user } = useUser();
  // 后续渲染逻辑不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:56:07