Search code examples
reactjsreact-router-dom

Route handling a uniquely generated URL specific to a user in ReactJS and react-router-dom v4


In the app I am working on if a user forgot their password, they click on a link that brings them to a page where they enter the username. If the username is matched, it sends a uniquely generated URL to the email associated with the username. For example:

http://localhost:8000/auth/security_questions/0e51706361e7a74a550e995b415409fdab4c66f0d201c25cb4fa578959d11ffa

All of this works fine, but I am trying to figure out how to handle this on the front-end routing using React and react-router-dom v4. I made this route.

<Route exact path='/auth/security_questions/:key' component={SecurityQuestions} />

The correct component loads related to security questions, but that is not the behavior I am after. After all, it takes anything you put after security_questions/.

What it should be doing is matching :key against the database before it loads the component.

I'm not sure about a few things:

1) How to parse out the :key portion so that I can pass it as a value to verify against the database.

2) While I have a general idea of how to handle the verification, I am not sure how to tell React: "Ok, the key has been verified in the database. Finish loading the component."

I think it would in general look like:

// ./containers/security_questions.js

componentWillMount() {
    this.props.verifyKey(:key);
}

And then actions:

// ./actions/authentication.index.js

export function verifyKey({ :key }) {
    return function(dispatch) {
        axios
            .post(
                `${ROOT_URL}/api/auth/security_questions/`, 
                { :key }
            )
            .then(response => {

                dispatch('Finish loading the rest of the component')
            })
            .catch(error => {
                dispatch(authError(error.response.data.non_field_errors[0]));
            });
    }
}

Or maybe instead of it finishing loading the component, it should just route to a different URL that is a protected route.


Solution

    1. You can grab the params from the path like so (https://reacttraining.com/react-router/web/api/Route):

      <Route path="/user/:username" component={User}/>
      
      const User = ({ match }) => <h1>Hello {match.params.username}!</h1>
      
    2. You will want to conditionally render based upon some state set by verifyKey.

      componentWillMount() {
        this.props.verifyKey(this.props.match.params.key);
      }
      
      render() {
        if (this.state.permitRender) {
          return <Component>
        } else {
          return <LoadingComponent />
      }