我现在还很陌生,所以这可能是一个简单的问题。如果标题不正确,请提前道歉。
我正在尝试使用react-router-dom做一条受保护的路由。我以为我的代码正确,但是由于某些原因,当用户登录并调用PrivateRoute时,身份验证信息可能没有正确传递,这可能是我的ID-10-T错误。下面是我的代码和单击/ dashboard route时的控制台日志片段。
import React, { Component } from 'react';
import axios from 'axios'
import {
BrowserRouter as Router,
Route,
Redirect,
Switch
} from "react-router-dom";
import './App.css';
import Dashboard from "./pages/Dashboard";
import Home from "./pages/Home";
import NoMatch from "./pages/NoMatch";
import Signin from "./pages/Signin";
import Signup from "./pages/Signup";
class App extends Component {
constructor(props) {
super()
this.state = {
isAuthenticated: null,
loggedIn: false,
username: null
}
this.getUser = this.getUser.bind(this)
this.componentWillMount = this.componentWillMount.bind(this)
}
componentWillMount() {
this.getUser()
}
getUser() {
axios.get('/api/auth/user')
.then(res => {
console.log('Get user response: ')
console.log(res.data)
if (res.data.user) {
console.log('Get User: There is a user saved in the server session: ')
console.log(res.data.user)
this.setState({
isAuthenticated: true,
loggedIn: true,
username: res.data.user.username
})
console.log("this.state.isAuthenticated value:")
console.log(this.state.isAuthenticated)
} else {
console.log('Get user: no user');
this.setState({
isAuthenticated: false,
loggedIn: false,
username: null
})
console.log("this.state.isAuthenticated value:")
console.log(this.state.isAuthenticated)
}
})
.catch((err) => {
console.log('Error fetching authorized user.');
console.log(err)
});
}
render() {
return (
<div>
<Router>
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/signin" component={Signin} />
<Route exact path="/signup" component={Signup} />
<PrivateRoute
authed={this.state.isAuthenticated}
path="/dashboard"
component={Dashboard} />
<Route component={NoMatch} />
</Switch>
</div>
</Router>
</div>
)
}
}
function PrivateRoute({ component: Component, authed, ...rest }) {
console.log("PrivateRoute")
console.log("authed value:")
console.log(authed)
return (
<Route
{...rest}
render={(props) => (authed === true)
? (<Component {...props} />)
: (<Redirect
to={{
pathname: '/signin',
state: { from: props.location }
}}
/>)}
/>
)
}
export default App;
控制台输出:
PrivateRoute
authed value:
null
Get user response:
{user: {…}}
Get User: There is a user saved in the server session:
{id: 1, firstname: "xxxx", lastname: "xxxx", username: "xxxx", email: "xxxx@xxxx.com", …}
this.state.isAuthenticated value:
true
似乎在componentWillMount之前正在处理PrivateRoute,但是我不确定如何防止这种情况。
任何帮助将不胜感激。
答案 0 :(得分:0)
您可能需要在代码中解决一些问题。
componentWillMount
或任何生命周期方法。componentWillMount
更改为componentDidMount
。在挂载componentWillMount
组件之前调用作为App
挂载的组件之后,最好进行api调用。PrivateRoute
仅在调用App
组件的render方法时才被调用。但是由于所有API调用都是异步的,因此App
组件的render方法将在API调用成功之前被调用,因为所有API调用在JavaScript中都是异步的。并且当API调用成功时,状态将被更新,并且App
组件将以更新后的状态重新呈现。这是解决上述问题的更新代码。
class App extends Component {
constructor(props) {
super()
this.state = {
isAuthenticated: false, // change null to false
loggedIn: false,
username: null
}
this.getUser = this.getUser.bind(this)
// this.componentWillMount = this.componentWillMount.bind(this)
}
componentDidMount() {
this.getUser()
}
getUser() {
axios.get('/api/auth/user')
.then(res => {
console.log('Get user response: ')
console.log(res.data)
if (res.data.user) {
console.log('Get User: There is a user saved in the server session: ')
console.log(res.data.user)
this.setState({
isAuthenticated: true,
loggedIn: true,
username: res.data.user.username
})
console.log("this.state.isAuthenticated value:")
console.log(this.state.isAuthenticated)
} else {
console.log('Get user: no user');
this.setState({
isAuthenticated: false,
loggedIn: false,
username: null
})
console.log("this.state.isAuthenticated value:")
console.log(this.state.isAuthenticated)
}
})
.catch((err) => {
console.log('Error fetching authorized user.');
console.log(err)
});
}
render() {
return (
<div>
<Router>
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/signin" component={Signin} />
<Route exact path="/signup" component={Signup} />
<PrivateRoute
authed={this.state.isAuthenticated}
path="/dashboard"
component={Dashboard} />
<Route component={NoMatch} />
</Switch>
</div>
</Router>
</div>
)
}
}
function PrivateRoute({ component: Component, authed, ...rest }) {
console.log("PrivateRoute")
console.log("authed value:")
console.log(authed)
return (
<Route
{...rest}
render={(props) => (authed === true)
? (<Component {...props} />)
: (<Redirect
to={{
pathname: '/signin',
state: { from: props.location }
}}
/>)}
/>
)
}
export default App;