javascript - Validating URL Parameters in React Router v4 - Stack Overflow

I'd like to figure out a way to validate a Route path like this items:id in React Router v4. I w

I'd like to figure out a way to validate a Route path like this /items/:id in React Router v4. I want to check if this item exists in the database (thus requiring a Promise or async call) before proceeding to either render the ItemPage ponent or Redirect ponent to the login page. I've been trying to follow the pattern at but the validation does not require an async call. When I try to do something like

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

I get Objects are not valid as a React child (found: [object Promise]). How can I make an async validation of a Route param?

I'd like to figure out a way to validate a Route path like this /items/:id in React Router v4. I want to check if this item exists in the database (thus requiring a Promise or async call) before proceeding to either render the ItemPage ponent or Redirect ponent to the login page. I've been trying to follow the pattern at https://reacttraining./react-router/web/example/auth-workflow but the validation does not require an async call. When I try to do something like

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

I get Objects are not valid as a React child (found: [object Promise]). How can I make an async validation of a Route param?

Share Improve this question asked Oct 29, 2017 at 18:00 user8129767user8129767
Add a ment  | 

1 Answer 1

Reset to default 9

Update: I tried two approaches.

Higher Order Components: I created 2 higher order ponents, AuthenticatedRoute and ValidatedRoute:

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;

And

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

let ValidatedRoute = ComposedComponent => class extends Component {
  state = {
    isValid: true
  }

  async ponentDidMount() {
    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;

To use them, I wrapped the ponent that was being used for that route with AuthenticatedRoute(ValidatedRoute(ponent)). The advantage was that this allowed neat organization of authenticated vs. validated routes, but this had to be done in the ponents themselves, not in the router file. I just used regular Router there. So calling it in the route file looked like:

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

The other option was to create a PrivateRoute ponent:

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

class PrivateRoute extends Component {
  state = {
    authenticated: true,
    validated: true
  }

  async ponentDidMount() {
    if (this.props.validator) {
      this.setState({
        validated: await this.props.validator(this.props.putedMatch.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;

And it had to be called like:

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

Still feeling pretty anti-pattern and the React-Router-V4 docs aren't much with this. I went with HOCs since it felt a little more organized.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743735437a4498173.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信