【问题标题】:history.push() redirects on hard-coded path, but not with the one provided by statehistory.push() 重定向硬编码路径,但不使用 state 提供的路径
【发布时间】:2019-02-20 07:03:15
【问题描述】:

我有以下私有路由,当未经授权的用户尝试访问时,会将用户重定向到登录组件(见下文)。

<PrivateRoute path="/checkout/step1" component={Address} />

PrivateRoute 的代码如下:

import React from "react";
import { Redirect, Route } from "react-router-dom";

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={props =>
      localStorage.getItem("token") ? (
        <Component {...props} />
      ) : (
        <Redirect
          to={{
            pathname: "/login",
            state: { from: props.location }
          }}
        />
      )
    }
  />
);

export default PrivateRoute;

在我的登录组件中,我想在成功登录后将用户重定向回私有路由:

class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: "",
      path: ""
    };
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    let pathname = "/";
    // need try-catch, since 
    // this.props.history.location.state.from.pathname
    // might be inaccessible resource
    try {
      pathname = this.props.history.location.state.from.pathname;
    } catch (err) {
      console.log("Resource inaccessible.");
    }
    this.setState({ path: pathname });
  }

  handleSubmit = e => {
    e.preventDefault();
    // authentication
    this.props.onAuth(this.state.email, this.state.password);

    // this.props.history.push(this.state.path); // not working
    // this.props.history.push("/about"); // working fine
  };

  renderLoginForm = token => {
    // ... skipped
  };

  render() {
    const { token } = this.props;

    return (
      <React.Fragment>
        {this.renderLoginForm(token)}
      </React.Fragment>
    );
  }
}

try-catch 块中的pathname 获取适当的值,当用户尝试访问私有路由时,默认为/,以防用户从常规路由登录。

我有一个奇怪的问题,this.props.history.push() 正确重定向硬编码路径,但对于从状态它只是重定向到 / 的路径。我找不到这个特定问题的答案。

这可能与这个问题无关,但我只想提一下 LoginAddress 两个组件都连接到 Redux 存储。

【问题讨论】:

    标签: reactjs redux react-redux react-router


    【解决方案1】:

    由于 this.setState 是异步触发的,因此您应该将其放在 try catch 中:

    componentDidMount() {
    let pathname = "/";
    // need try-catch, since 
    // this.props.history.location.state.from.pathname
    // might be inaccessible resource
    try {
      pathname = this.props.history.location.state.from.pathname;
      this.setState({ path: pathname });
    } catch (err) {
      console.log("Resource inaccessible.");
      this.setState({ path: pathname });
    }   
    }
    

    您还可以使用带有 if 语句的异步函数以更简洁的方式执行此操作,以评估 this.props.history... 是否存在。希望对您有所帮助。

    【讨论】:

    • 不幸的是,这不起作用。另外,您能否详细说明一下这个异步函数?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 2014-06-30
    • 1970-01-01
    • 2021-02-07
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多