【问题标题】:Validating URL Parameters in React Router v4在 React Router v4 中验证 URL 参数
【发布时间】:2018-04-10 17:40:28
【问题描述】:

我想想办法在 React Router v4 中验证像 /items/:id 这样的路由路径。在继续将ItemPage 组件或Redirect 组件呈现到登录页面之前,我想检查该项目是否存在于数据库中(因此需要 Promise 或异步调用)。我一直在尝试遵循https://reacttraining.com/react-router/web/example/auth-workflow 的模式,但验证不需要异步调用。当我尝试做类似的事情时

const ValidatedRoute = async ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    await param.isValid? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

我得到Objects are not valid as a React child (found: [object Promise]). 我如何对Route 参数进行异步验证?

【问题讨论】:

    标签: javascript reactjs validation react-router react-router-v4


    【解决方案1】:

    更新:我尝试了两种方法。

    高阶组件:我创建了 2 个高阶组件,AuthenticatedRouteValidatedRoute

    import React, { Component } from "react";
    import { Redirect } from "react-router-dom";
    
    let AuthenticatedRoute = ComposedComponent => class extends Component {
      render() {
        if (!sessionStorage.jwt) {
          return <Redirect to={{
            pathname: '/login',
            state: { from: this.props.location }
          }}/>
        }
        return <ComposedComponent {...this.props} />
      }
    }
    
    export default AuthenticatedRoute;
    

    import React, { Component } from "react";
    import { Redirect } from "react-router-dom";
    
    let ValidatedRoute = ComposedComponent => class extends Component {
      state = {
        isValid: true
      }
    
      async componentDidMount() {
        this.setState({
          isValid: await this.props.validator(this.props.match.params.id)
        })
      }
    
      render() {
        if (!this.state.isValid) {
          return <Redirect to={{
            pathname: this.props.redirect,
            state: { from: this.props.location }
          }}/>
        }
        return <ComposedComponent {...this.props} />
      }
    }
    
    export default ValidatedRoute;
    

    为了使用它们,我用AuthenticatedRoute(ValidatedRoute(component)) 包装了用于该路由的组件。优点是这允许对经过验证的路由和经过验证的路由进行整齐的组织,但这必须在组件本身中完成,而不是在路由器文件中。我只是在那里使用了普通的Router。所以在路由文件中调用它看起来像:

    <Route exact path="/list/:id" render={(props) => <ProtectedComponent
                  validator={Validator}
                  redirect='/'
                  {...props}
                  />
                } />
    

    另一个选项是创建一个PrivateRoute 组件:

    import React, { Component } from "react";
    import { Redirect, Route } from "react-router-dom";
    
    class PrivateRoute extends Component {
      state = {
        authenticated: true,
        validated: true
      }
    
      async componentDidMount() {
        if (this.props.validator) {
          this.setState({
            validated: await this.props.validator(this.props.computedMatch.params.id)
          });
        }
      }
    
      render() {
        if (this.props.authenticate && !sessionStorage.jwt) {
          return <Redirect to={{
            pathname: '/login',
            state: { from: this.props.location }
          }}/>
        }
    
        if (!this.state.validated) {
          return <Redirect to={{
            pathname: this.props.redirect,
            state: { from: this.props.location }
          }}/>
        }
    
        return <Route {...this.props} />
      }
    }
    
    export default PrivateRoute;
    

    它必须被称为:

    <PrivateRoute exact path="/list/:id"
              authenticate={true}
              component={ProtectedComponent}
              validator={validator}
              redirect='/'
            />
    

    仍然感觉非常反模式,React-Router-V4 文档对此并不多。我选择了 HOC,因为它感觉更有条理。

    【讨论】:

      猜你喜欢
      • 2018-02-28
      • 2018-02-20
      • 1970-01-01
      • 2018-05-02
      • 2018-01-10
      • 2016-10-23
      • 2019-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多