React中使用useHistory跳转传递State后无法接收Props的问题
问题分析与解决方案
看起来你在React路由跳转和状态管理上踩了几个典型的坑,我来帮你一步步梳理并修复:
核心问题拆解
check函数无法获取路由props:你直接调用check(props)的方式并不能自动拿到React Router的路由上下文props,所以控制台会显示props为undefined。- 登录状态未用React状态管理:你用了一个
isLoggedIn变量,但没有通过useState这类状态钩子维护,就算拿到了跳转的state,组件也不会触发重新渲染来切换Navbar。 - 重复渲染
BrowserRouter:在if/else里分别渲染BrowserRouter会重置路由上下文,导致你通过history.replace传递的state直接丢失。
分步修复方案
1. 用React状态管理登录状态
首先在App组件里引入useState,把登录状态变成可响应的React状态:
import { useState, useEffect } from 'react'; import { BrowserRouter, Switch, Route, useLocation } from 'react-router-dom'; function App() { // 初始化登录状态为false const [isLoggedIn, setIsLoggedIn] = useState(false); // 获取路由location对象,用来读取跳转时传递的state const location = useLocation(); // 监听路由变化,处理跳转时的登录状态 useEffect(() => { // 如果跳转时携带了login: true的state,更新登录状态 if (location.state?.login) { setIsLoggedIn(true); } }, [location]); // 剩下的路由逻辑写在这里 }
2. 重构路由结构,避免重复渲染BrowserRouter
BrowserRouter只需要在最外层渲染一次,内部根据登录状态切换Navbar和路由即可:
function App() { const [isLoggedIn, setIsLoggedIn] = useState(false); const location = useLocation(); useEffect(() => { if (location.state?.login) { setIsLoggedIn(true); } }, [location]); return ( <BrowserRouter> {/* 根据登录状态渲染对应的Navbar */} {isLoggedIn ? <Navbars /> : <Navbars1 />} <Switch> {isLoggedIn ? ( // 登录后的路由集合 <> <Route path="/" component={Dashboard} exact /> <Route path="/math" component={Math} /> <Route path="/reasoning" component={Reasoning} /> <Route path="/computer" component={Computer} /> <Route path="/english" component={English} /> </> ) : ( // 未登录时的路由集合 <> <Route path="/" component={Home} exact /> <Route path="/login" render={(props) => ( <Login {...props} setLoginStatus={setIsLoggedIn} /> )}/> <Route path="/signup" component={Signup} /> </> )} </Switch> </BrowserRouter> ); }
3. 优化登录组件的跳转逻辑
在Login组件里,登录成功后可以直接调用setLoginStatus更新状态,这样比依赖location.state更可靠:
// Login组件中的axios请求逻辑 axios.post('http://localhost:3020/login', { email: email, password: password }) .then(function (response) { console.log(response.data); // 直接更新App组件中的登录状态 props.setLoginStatus(true); // 跳转到首页 props.history.replace('/'); })
为什么之前的代码不生效?
- 直接调用
check(props)无法获取React Router的路由props,只有路由组件或通过render/component渲染的组件才能自动拿到这些props。 - 重复渲染
BrowserRouter会重置路由上下文,导致跳转时传递的state被清空。 - 没有用React状态管理
isLoggedIn,就算拿到了state,组件也不会触发重新渲染来切换Navbar。
内容的提问来源于stack exchange,提问作者Piyush Jaiswal
相关产品推荐
相关产品推荐

