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

React-Router v6路由传递State为null问题求助

问题原因与解决方案

核心问题

你在Link组件的state中传递了setToken函数,而react-router的state仅支持可序列化数据(字符串、数字、普通对象等),函数无法被序列化,这会导致整个state传递失败,最终useLocation()获取到的state为null。

另外,直接通过手动输入URL、刷新页面访问路由时,state也会丢失(因为state存储在内存中,并非URL的一部分),这也是常见的state为null的场景。


解决方案:用Context API全局共享状态

既然需要在多个页面组件中共享token和setToken,直接通过Link传state不是最优方案,推荐使用React Context API实现全局状态共享:

1. 创建AuthContext文件

新建AuthContext.js:

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

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [token, setToken] = useState(false);

  return (
    <AuthContext.Provider value={{ token, setToken }}>
      {children}
    </AuthContext.Provider>
  );
}

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

2. 修改App.js,用AuthProvider包裹路由

import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import { AuthProvider } from './AuthContext';
import SearchPage from './pages/Search.page';
import HomePage from './pages/Home.page';
import ProfilePage from './pages/Profile.page';
import AddEntryPage from './pages/AddEntry.page';
import LoginPage from "./pages/Login.page";
import CreateUserPage from "./pages/CreateUser.page";
import './App.css';

function App() {
  return (
      <AuthProvider>
        <Router>
            <div>
              <nav>
                <ul>
                  <li>
                    <Link to='/profile'>Profile</Link>
                  </li>
                  <li className='right-edge-pusher'>
                    <Link to='/'>Home</Link>
                  </li>
                  <li>
                    <Link to='/add'>Add</Link>
                  </li>
                  <li>
                    <Link to='/search'>Search</Link>
                  </li>
                </ul>
              </nav>
              <Routes>
                <Route path='/' element={<HomePage /> }/>
                <Route path='/profile' element={<ProfilePage />}/>
                <Route path='/add' element={<AddEntryPage />}/>
                <Route path='/search' element={<SearchPage />}/>
                <Route path="/login" element={<LoginPage /> }/>
                <Route path="/user" element={<CreateUserPage /> }/>
              </Routes>
            </div>
          </Router>
      </AuthProvider>
  );
}

export default App;

3. 修改ProfilePage.js,通过useAuth获取状态

import { useState } from "react";
import { useQuery } from "react-query";
import { Link } from 'react-router-dom';
import { useAuth } from '../AuthContext';
import axios from 'axios';
import PostSnippet from '../components/PostSnippet';

function ProfilePage() {
    const { token, setToken } = useAuth();
    console.log(token);

    const [enabled, setEnabled] = useState(false);

    const fetchProfile = () => {
        return axios.get("http://localhost:5000/saved")
    }
    const { data, isError, error, isLoading } = useQuery('profile', fetchProfile, { enabled });

    return ( 
        <div>
            { !token && 
                <>
                    <Link to={'/login'}>Login</Link>
                    <br/>
                    <br/>
                    <Link to={'/user'}>Create User</Link>
                </>
            }
            { isLoading && <h2>Loading...</h2> }
            { isError && <h2>{error.response.data.message.message}</h2> }
            { data && 
                data.data.map(item => {
                    return (
                        <PostSnippet 
                            key={item.id}
                            plantName={item.name}
                            plantTempRange={`${item.sow_temp_range}f`}
                            plantZone={item.planting_zone}
                            plantSunReq={`${item.sun_req} sun`}
                            plantDescription='To be added...'
                        />
                    );
                })
            }
        </div>
     );
}

export default ProfilePage;

额外注意事项

  • 如果必须使用Link传state,确保只传递可序列化数据,不要包含函数、Symbol等不可序列化类型。
  • 刷新页面或手动输入URL时,state会丢失,这种场景下可以给state设置默认值,或者将关键状态存储在localStorage/sessionStorage中,组件初始化时从本地存储恢复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:35:14