React router private route not getting props from state (e.g. authentication state)
我正在尝试实现一个私有路由组件来重定向未通过身份验证的用户。问题是当我渲染像 <PrivateRoute authenticated={this.state.isAuthenticated} path=’/private’ component={Panel} currentUser={this.state.currentUser} 这样的组件时,私有路由会将经过身份验证的用户重定向到登录页面,而不是转到面板。
在 App.js 中,我渲染了所有的路由,包括 <PrivateRoute/>,我在 ComponentDidMount() 中设置了 currentUser 和 isAuthenticated 状态变量,但我无法将它们传递给 PrivateRoute。
App.js
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
//imports…
class App extends Component { state = { loadCurrentUser = () => { componentDidMount() { handleLogin = () => { render () { <Route export default withRouter(App); |
请注意,<Navigation /> 组件确实获得了正确的状态变量。
PrivateRoute.js
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//imports…
const PrivateRoute = ({ component: Component, authenticated, …rest }) => ( <Route {…rest} render={props => authenticated ? ( <Component {…rest} {…props} /> ) : ( <Redirect to={{ pathname: ‘/login’, state: { from: props.location } }} /> ) } /> ); export default PrivateRoute |
- 你好 !刚刚给你写了一个解决方案和一个沙箱供你参考。如果您有任何问题,请告诉我:)
问题与 PrivateRoute 组件在第一次渲染时没有任何来自主 App 组件的更新道具有关。
如果您直接导航到 PrivateRoute 路径而不先进入任何其他路由,您将被重定向回 /login。您的 PrivateRoute 尝试在父 App\\ 的 componentDidMount() 逻辑完成之前呈现。所以 isAuthenticated 被传递为假。
如果您从 Home 或 Login 开始,然后使用 Link 转到 PrivateRoute,则会发生相反的情况。
最终,这就是为什么人们使用像 redux 这样的状态管理工具来让经过身份验证的状态在全球范围内共享,而不是通过父组件传递。
虽然有一个解决方法!
参考沙箱:https://codesandbox.io/s/intelligent-dan-uskcy
App 组件是否曾被初始化。我们称之为
wasInitialized
我们直接进入它的组件路径,在 App 有机会完成它的 componentDidMount() 逻辑之前,wasInitialized 将为 false。
相反,我们将只显示一个空字符串,给父 App\\’s
componentDidMount() 时间来执行和更新
isAuthenticated 值。
现在让我们看一下这一行:
<Route {…rest} render={props => auth === true ? <Component
{…props} /> : !wasInitialized ? “” : <Redirect to=”/login” />
}
在下一次重新渲染中,isAuthenticated 将是 true 或
错误的。如果用户是Authenticated,我们渲染预期的组件。如果用户未通过身份验证,我们进行下一个检查。现在 wasInitialized 的值为 true,因此 check 的计算结果为 false。因此,由于两个检查都没有通过,我们重定向到 /login.
应用程序.js
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
class App extends Component {
state = { loadCurrentUser = () => { componentDidMount() { handleLogin = () => { <Route export default withRouter(App); |
私人的
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import React from”react”;
import { Route, Redirect } from”react-router-dom”; const PrivateRoute = ({ export default PrivateRoute; |
- 是的,这就是我的想法,但我不知道如何解决。谢谢!顺便说一句,在解决方案中,App.js 应该已经在状态下被初始化了。
来源:https://www.codenong.com/56718685/
