反应路由器 dom 重定向问题。更改 url,不渲染组件
Posted
技术标签:
【中文标题】反应路由器 dom 重定向问题。更改 url,不渲染组件【英文标题】:React router dom redirect problem. Changes url, does not render component 【发布时间】:2019-11-29 15:35:59 【问题描述】:问题:当我使用history.push()
时,我可以看到浏览器更改了 url,但它并没有呈现我的组件在路径上侦听。只有在我刷新页面时才会呈现。
App.js
文件:
import React from "react";
import BrowserRouter as Router, Route from "react-router-dom";
import Provider from "react-redux";
import PropTypes from "prop-types";
//Components
import LoginForm from "../LoginForm/LoginForm";
import PrivateRoute from "../PrivateRoute/PrivateRoute";
import ServerList from "../ServerList/ServerList";
const App = ( store ) =>
const isLoggedIn = localStorage.getItem("userToken");
return (
<Router>
<Provider store=store>
<div className="App">
isLoggedIn !== true && (
<Route exact path="/login" component=LoginForm />
)
<PrivateRoute
isLoggedIn=!!isLoggedIn
path="/"
component=ServerList
/>
</div>
</Provider>
</Router>
);
;
App.propTypes =
store: PropTypes.object.isRequired
;
export default App;
在我的 LoginForm
中,我正在向 API 发出请求,在完成我的程序后,我使用 .then()
重定向我的用户:
.then(() =>
props.history.push("/");
)
会发生什么:浏览器将 url 从 /login
更改为 /
,但不会呈现侦听 /
路由的组件,除非我重新加载页面。
在我的/
组件中,我使用useEffect()
钩子向API 发出另一个请求,它获取数据并将其打印到return()
中。如果我在console.log
内useEffect()
它发生两次,我假设是第一次,当我使用useState()
钩子将来自API 的数据存储在组件的状态内时。
编辑:按要求添加PrivateRoute
组件:
import React from "react";
import Route, Redirect from "react-router-dom";
const PrivateRoute = ( component: Component, isLoggedIn, ...rest ) =>
return (
<Route
...rest
render=props =>
isLoggedIn === true ? (
<Component ...props />
) : (
<Redirect to= pathname: "/login" />
)
/>
);
;
export default PrivateRoute;
我已经尝试过的:
1)用withRouter()
包裹我的default export
:
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(LoginForm));
2) 创建自定义history
并将其作为prop
传递给Router
。
react-router-dom
版本是^5.0.1
。 react-router
同理,5.0.1
【问题讨论】:
看起来你的PrivateRoute
总是挂载的。你需要显示privateroute组件
@Panther,将原帖更新为PrivateRoute
。
这看起来也像它的渲染.. 你能检查一下 React 调试器面板,看看什么没有渲染.. 问题会在那里
【参考方案1】:
您的代码中有两个错误。
您没有使用<switch>
组件来包装路由。因此,在每次渲染时都会处理所有路由,并且会渲染来自每个 <route>
的所有组件。
您正在使用本地存储在组件之间交换信息。但是本地存储中的更改是不可见的,因此它不会触发组件重新渲染。要纠正这个问题,您应该在 App
组件中使用本地状态(通过将其转换为类或使用挂钩)。
修正后的代码如下所示
const App = ( store ) =>
const [userToken, setUserToken] = useState(localStorage.getItem("userToken")); // You can read user token from local store. So on after token is received, user is not asked for login
return (
<Router>
<Provider store=store>
<div className="App">
<Switch>
!!userToken !== true && (
<Route exact path="/login"
render=props => <LoginForm ...props setUserToken=setUserToken />
/>
)
<PrivateRoute
isLoggedIn=!!userToken
path="/"
component=ServerList
/>
</Switch>
</div>
</Provider>
</Router>
);
;
并且LoginForm
应该使用setUserToken
来更改App
组件中的用户令牌。它还可以将用户令牌存储在本地存储中,因此页面刷新用户不会被要求登录,而是使用存储的令牌。
除了<Route>
之外,请确保不要在<Switch>
和</Switch>
之间放置任何内容。否则路由将不起作用。
这里是working sample
【讨论】:
以上是关于反应路由器 dom 重定向问题。更改 url,不渲染组件的主要内容,如果未能解决你的问题,请参考以下文章