React Router Auth重定向遇到问题

时间:2019-08-03 05:33:34

标签: reactjs react-router

我正在尝试使用此处显示的反应路由器身份验证重定向(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>

  );`

1 个答案:

答案 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>
  );
}
  }

或将函数表达式更改为常规函数都可以!