【问题标题】:How to resolve promise before redirecting to Private Route in React?如何在 React 重定向到 Private Route 之前解决 Promise?
【发布时间】:2020-03-27 19:11:18
【问题描述】:

用例

我想在用户尝试访问私人路线时拨打async() 电话。通常在重定向到私有路由时使用同步方法。

这是我使用过的代码,但不明白如何使用异步方法。

class PrivateRoute extends Component {
  constructor(props) {
    super(props);

    this.state = {
      isAdmin: null
    };
  }

  componentDidMount() {
    console.log("PrivateRoute");
    verifyUser().then(res => {
      this.setState({
        isAdmin: res
      });
    });
  }

  render() {
    const { component: Component, ...rest } = this.props;
    return (
      <Route
        {...rest}
        render={props =>
          this.state.isAdmin === true ? (
            <InnerLayout>
              <Component {...props} />
            </InnerLayout>
          ) : this.state.isAdmin === null ? (
            <div>Loading...</div>
          ) : (
            <Redirect
              to={{ pathname: "/Login", state: { from: this.props.location } }}
            />
          )
        }
      />
    );
  }
}

export default PrivateRoute;

上述代码的问题是 componentDidMount() 调用一次。我检查了React routing and private routes Question 并检查了Authenticate async with react-router-v4 question,但两个答案都对我不起作用。

如果我尝试在渲染中解决承诺,则会显示以下错误:

我怎样才能实现这个用例?

【问题讨论】:

  • 尝试使用 HOC 可能
  • 你的项目中没有使用 redux 吗?
  • @AyushGupta 什么是 HOC?
  • @m.sohail 不,我只使用 React。没用过redux
  • 高阶组件

标签: reactjs react-router


【解决方案1】:

你可以使用 withRouter (https://reacttraining.com/react-router/web/api/withRouter)

class PrivateRoute extends Component {
    constructor(props) {
        super(props);

        this.state = {
            isAdmin: null
        }
    }

    componentDidMount() {
        console.log('PrivateRoute');
        verifyUser().then(res => {
            if(!res){
             this.props.history.push('/Login')
           }else
            this.setState({
                isAdmin: res
            })
        });
    }

    render() {
        const { component: Component, ...rest } = this.props;
       if(this.state.isAdmin === null) return <div>Loading ...</div>
       return <Route {...rest} render={props => <InnerLayout><Component/></InnerLayout>}
    }
}

export default withRouter(PrivateRoute);

【讨论】:

  • componentDidMount() 方法只调用一次。之后,每当用户点击其他私有路由时,该方法将不会调用。
【解决方案2】:

我认为你用组件包装路由,然后再次包装路由,尝试为你的代码创建语句并创建不同的方法,不要渲染方法。

<Route {...rest} render={props =>
                this.state.isAdmin === true ? (<InnerLayout><Component {...props} /></InnerLayout>) :
                    (this.state.isAdmin === null ? (<div>Loading...</div>) : 
                        (<Redirect to={{ pathname: '/Login', state: { from: this.props.location } }} />)) }/>
            );

制作方法:

verify = () => {

 ... your statement
}

然后调用render方法

render () {
return {this.verify()}
}

因为有时关于渲染的声明不能正常工作。

【讨论】:

  • 这会有什么不同?
【解决方案3】:

对于我的用例,componentWillReceiveProps() 方法运行良好。以下我添加的代码对我有用。

componentWillReceiveProps() {
        verifyReceivedSign().then((res) => {
            this.setState({
                isAdmin: res
            })
        });
    }

您在给定链接中了解更多关于componentWillReceiveProps() 的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2019-05-28
    • 2021-05-01
    相关资源
    最近更新 更多