我有一个受保护的URL-如果用户试图呈现不允许访问的页面(这是在ReactJS组件中),这是我如何重定向用户的方法:
render() {
if(!this.props.auth.isAuthenticated) {
this.props.history.push('/');
}
...
他未登录时,已在主页上重定向。但是在控制台中,我遇到了这两个错误:
index.js:2178 Warning: Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
该消息表明我可以将if
块移动到componentWillMount
吗?但是,componentWillMount
是否不被淘汰?
和第二条错误消息:
xhr.js:178 GET http://localhost:3000/api/cars 401 (Unauthorized)
此消息是由NodeJS路由中的以下代码块引起的:
router.get('/cars', passport.authenticate('jwt'), function(req, res, next) {
if (req.isAuthenticated()) {
console.log('logged in');
Car.find({}).sort('name').exec(function(err, cars) {
if(err) throw err;
res.send(JSON.stringify(cars));
});
} else {
// not logged in
console.log('not logged in');
//res.send(401);
}
});
如果用户未通过身份验证,则控制台中会引发401
错误,并且不会执行此路由内的代码。这是正确的行为吗?为什么控制台中仍然存在错误?
编辑: ReactJS组件:
class Car extends Component {
constructor() {
super();
this.state = {
name: '',
errors: {},
cars: []
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
UNSAFE_componentWillMount() {
if(!this.props.auth.isAuthenticated) {
this.props.history.push('/');
}
}
componentDidMount() {
//console.log('x');
//console.log(this.props.auth);
//let self = this;
axios.get('/api/cars')
.then((response) => {
this.setState({cars: response.data});
}).catch(err => {
console.log('CAUGHT IT! -> ', err);
if (err.response.status === 401) {
//this.props.history.push('/');
}
return err;
})
}
componentWillReceiveProps(nextProps) {
if(nextProps.auth.isAuthenticated) {
this.props.history.push('/')
}
if(nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
handleInputChange(e) {
this.setState({
[e.target.name]: e.target.value
})
}
handleSubmit(e) {
e.preventDefault();
const car = {
name: this.state.name
}
console.log(car);
axios.post('/api/cars/create', car)
.then(function(response) {
console.log('response.data: ', response.data);
if(response.data == "success"){
console.log('successssss');
}
}).catch(function(err) {
console.log(err)
});
}
render() { ...
答案 0 :(得分:0)
请避免在一个堆栈溢出问题中提出多个问题
错误1:
该错误消息明确指出,您不应导航到render方法中的另一个页面。但是,您正在这样做。消息提示您可以在componentWillMount livecycle方法中移动代码,但请注意,此检查将不会在每次重新渲染时运行。
错误2:
您似乎正在呼叫此路由,该路由未经身份验证而受到身份验证的保护。没有看到您的客户端代码,我无法进一步评论。
答案 1 :(得分:0)
Patrick解释了上述错误。 componentWillMount生命周期方法。据我所知,不被弃用。
我猜您正在使用React Router满足您的路由需求。 react router private route example是如何正确执行此操作的一个很好的示例 它使用来自react-router-dom的Route和Redirect并创建一个特殊的PrivateRoute组件。对于需要身份验证并重定向未经授权的用户的每条路由,您将使用此PrivateRoute组件,而不仅仅是Route组件。
您可以检查身份验证,并在需要时在render Lifecycle方法内渲染其他内容。但是您不应该从render方法内部重定向。
答案 2 :(得分:0)
您可以这样重定向用户:
import {Redirect} from 'react-router-dom';
...//inside constructor
this.state={
redirect_path:''//redirect_path is the path you want to redirect the user to
}
在componentDidMount中,检查用户是否已获得授权,
如果不是:
this.setState({
redirect_path:'path_to_redirect_to'
})
在渲染方法中:
render()
{ //push will add it to the browser history
if(this.state.redir)
{
return(
<Redirect push to={this.state.redirect_path} />
}
else
{
//return the page
}
}