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

如何在使用RouterProvider的React项目中创建全局可访问修改的状态?

在React RouterProvider中实现全局状态管理

下面提供两种常用的全局状态实现方案,适配你的路由结构:


方法一:React Context API(原生无依赖方案)

适合中小项目,无需额外安装包,直接用React内置API实现。

1. 创建全局Context与Provider

新建src/contexts/UserContext.js文件,封装全局状态和操作方法:

import { createContext, useContext, useState } from 'react';

// 创建全局Context
const UserContext = createContext();

// 定义Provider组件,负责管理状态并传递给子组件
export function UserProvider({ children }) {
  // 全局状态示例:用户信息
  const [user, setUser] = useState(null);

  // 状态修改方法:登录
  const login = (userData) => {
    setUser(userData);
    // 可选:持久化到本地存储
    localStorage.setItem('user', JSON.stringify(userData));
  };

  // 状态修改方法:登出
  const logout = () => {
    setUser(null);
    localStorage.removeItem('user');
  };

  // 传递给子组件的状态和方法
  const contextValue = {
    user,
    login,
    logout
  };

  return <UserContext.Provider value={contextValue}>{children}</UserContext.Provider>;
}

// 自定义Hook,简化Context调用(避免重复写useContext)
export function useUser() {
  const context = useContext(UserContext);
  if (!context) {
    throw new Error('useUser必须在UserProvider内部使用');
  }
  return context;
}

2. 用Provider包裹RouterProvider

修改你的src/index.js,让所有路由页面都能访问全局状态:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import './index.css'
import { UserProvider } from './contexts/UserContext'; // 导入Provider

import Home from './pages/Home.jsx'
import Login from './pages/Login.jsx'
import SignUp from './pages/SignUp.jsx'

const router = createBrowserRouter([
  {path: '/', element: <Home />},
  {path: '/login', element: <Login />},
  {path: '/register', element: <SignUp />},
])

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    {/* 用UserProvider包裹RouterProvider */}
    <UserProvider>
      <RouterProvider router={router} />
    </UserProvider>
  </React.StrictMode>,
)

3. 在页面中使用全局状态

登录页(Login.jsx)修改状态:

import { useState } from 'react';
import { useUser } from '../contexts/UserContext';
import { useNavigate } from 'react-router-dom';

export default function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const { login } = useUser();
  const navigate = useNavigate();

  const handleSubmit = (e) => {
    e.preventDefault();
    // 模拟接口请求返回用户数据
    const mockUser = { email, id: 1, name: '测试用户' };
    login(mockUser);
    navigate('/'); // 登录成功跳首页
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="邮箱"
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="密码"
        required
      />
      <button type="submit">登录</button>
    </form>
  );
}

首页(Home.jsx)访问状态:

import { useUser } from '../contexts/UserContext';
import { useNavigate } from 'react-router-dom';

export default function Home() {
  const { user, logout } = useUser();
  const navigate = useNavigate();

  // 未登录则跳转登录页
  if (!user) {
    navigate('/login');
    return null;
  }

  return (
    <div>
      <h1>欢迎回来,{user.name}!</h1>
      <p>你的邮箱:{user.email}</p>
      <button onClick={logout}>登出</button>
    </div>
  );
}

方法二:Redux Toolkit(第三方状态管理)

适合复杂项目,当状态逻辑多、跨组件交互频繁时使用。

1. 安装依赖

npm install @reduxjs/toolkit react-redux

2. 创建Redux Store与Slice

新建src/app/store.js:

import { configureStore } from '@reduxjs/toolkit';
import userReducer from '../features/user/userSlice';

export const store = configureStore({
  reducer: {
    user: userReducer,
  },
});

新建src/features/user/userSlice.js:

import { createSlice } from '@reduxjs/toolkit';

// 初始状态
const initialState = {
  user: null,
};

// 定义状态切片
const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    // 设置用户信息
    setUser: (state, action) => {
      state.user = action.payload;
    },
    // 清除用户信息
    clearUser: (state) => {
      state.user = null;
    },
  },
});

export const { setUser, clearUser } = userSlice.actions;
export default userSlice.reducer;

3. 用Redux Provider包裹RouterProvider

修改src/index.js:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import './index.css'
import { Provider } from 'react-redux';
import { store } from './app/store'; // 导入Redux Store

import Home from './pages/Home.jsx'
import Login from './pages/Login.jsx'
import SignUp from './pages/SignUp.jsx'

const router = createBrowserRouter([
  {path: '/', element: <Home />},
  {path: '/login', element: <Login />},
  {path: '/register', element: <SignUp />},
])

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Provider store={store}>
      <RouterProvider router={router} />
    </Provider>
  </React.StrictMode>,
)

4. 在页面中使用Redux状态

登录页(Login.jsx)修改状态:

import { useState } from 'react';
import { useDispatch } from 'react-redux';
import { setUser } from '../features/user/userSlice';
import { useNavigate } from 'react-router-dom';

export default function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const dispatch = useDispatch();
  const navigate = useNavigate();

  const handleSubmit = (e) => {
    e.preventDefault();
    const mockUser = { email, id: 1, name: '测试用户' };
    dispatch(setUser(mockUser));
    navigate('/');
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 表单内容同前 */}
    </form>
  );
}

首页(Home.jsx)访问状态:

import { useSelector, useDispatch } from 'react-redux';
import { clearUser } from '../features/user/userSlice';
import { useNavigate } from 'react-router-dom';

export default function Home() {
  const user = useSelector(state => state.user.user);
  const dispatch = useDispatch();
  const navigate = useNavigate();

  if (!user) {
    navigate('/login');
    return null;
  }

  const handleLogout = () => {
    dispatch(clearUser());
    navigate('/login');
  };

  return (
    <div>
      <h1>欢迎回来,{user.name}!</h1>
      <button onClick={handleLogout}>登出</button>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:51:00