我正在尝试使用此处显示的反应路由器身份验证重定向(https://reacttraining.com/react-router/web/example/auth-workflow),但是我遇到了很多问题。我目前遇到错误:无法读取未定义的属性“状态”。我不知道我在做什么错。任何帮助将不胜感激。另外,我很想听听您对我的代码的任何注释/改进(这是我使用React的时候)。
错误来自Login类渲染函数中的{from} 这是codesandbox的链接,其中包含更完整的代码:https://codesandbox.io/embed/bold-mendel-hgvun
`const auth = {
isAuthenticated: false,
authenticate(callback) {
this.isAuthenticated = true;
setTimeout(callback, 30000);
},
signout(callback) {
this.isAuthenticated = false;
setTimeout(callback, 30000);
}
};
//Class Login:
handleSubmit(event){
event.preventDefault();
var payload = {
"email": this.state.email,
"password": this.state.password
}
axios.post({url}"/login", payload)
.then((res) => {
console.log(res);
if (res.data.status == "success") {
auth.authenticate(() => {
this.setState({ redirectToReferrer: true});
});
this.setState({authenticated: true});
this.setState({token: res.data.data.token})
}
}
render() {
let {from} = this.props.location.state || {from: {pathname: '/'}};
const { redirectToReferrer } = this.state;
if (redirectToReferrer == true) {
return <Redirect to={from} />
}
return (
<form>
<input value={this.state.email} onChange={this.handleChange} type="email" name="email" placeholder="Email" />
<input value={this.state.password} onChange={this.handleChange} type="password" name="password" placeholder="Password" />
<button type="submit" onClick={this.handleSubmit} className="btn btn-primary">Login</button>
</form>
);
}
}
const PrivateRoute = ({ component: Component, authed, ...rest }) => (
<Route {...rest} render={(props) => (
authed === true
? <Component {...props} />
: <Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)} />
);
//called in class App like this
render() {
const {authenticated}=this.state;
return(
<React.Fragment className='root'>
<Router>
<Switch>
<Route path="/login" render={() => <Login callbackToParent={this.loginCallback} /> }exact/>
<Route path="/register" render={() => <Register callbackFromParent={this.registerCallback} /> } exact/>
<PrivateRoute authed={authenticated} path="/" render={() => <Home tokenFromParent={this.state.token} /> } exact/>
</Switch>
</Router>
</React.Fragment>
);`
答案 0 :(得分:1)
我认为在使用this.props.location.state之后立即调用函数表达式PrivateRoute。如果您使用的是函数表达式,则必须在使用它之前声明它。
也许您可以尝试在渲染方法之前声明函数表达式
//Class Login:
handleSubmit(event){
event.preventDefault();
var payload = {
"email": this.state.email,
"password": this.state.password
}
axios.post({url}"/login", payload)
.then((res) => {
console.log(res);
if (res.data.status == "success") {
auth.authenticate(() => {
this.setState({ redirectToReferrer: true});
});
this.setState({authenticated: true});
this.setState({token: res.data.data.token})
}
}
// declare function expression here so that the interpreter reaches the code first before its being used
const PrivateRoute = ({ component: Component, authed, ...rest }) => (
<Route {...rest} render={(props) => (
authed === true
? <Component {...props} />
: <Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)} />
);
render() {
let {from} = this.props.location.state || {from: {pathname: '/'}};
const { redirectToReferrer } = this.state;
if (redirectToReferrer == true) {
return <Redirect to={from} />
}
return (
<form>
<input value={this.state.email} onChange={this.handleChange} type="email" name="email" placeholder="Email" />
<input value={this.state.password} onChange={this.handleChange} type="password" name="password" placeholder="Password" />
<button type="submit" onClick={this.handleSubmit} className="btn btn-primary">Login</button>
</form>
);
}
}
或将函数表达式更改为常规函数都可以!