dfsdigging
dfsdigging

Reputation: 345

Issue with routing in React when user directly hits url that requires id from another component

I have this issue that I am facing in react related to routing. There is this button which appears on the screen which appears only if the user is authenticated and thus it's a private route "/home/coupons".

When user clicks on any of the coupons ,I directed the user to

http://localhost:3000/coupons?id=6

Using this props.history:

        this.props.history.push({
                 pathname: '/coupons',
                 search: '?id='+id,

           })

I did the routing for this in my App.js:

<Route path="/coupons" component={CouponsRedeem}/>

The Component CouponsRedeem needs the id from the Component where users gets directed when he hits /home/coupons.

My concern is that if user directly hits the route /coupons without navigating to /home/coupons,the entire web app break since we don't get any get anything in this.props.location.

How do I make sure that such things don't happen?

Is my routing done correctly?

Any suggestions are most welcomed. If it lacks information ,I will add more code snippets. I am using react-router.

Upvotes: 1

Views: 52

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281744

The solution to your problem is pretty simply. Either you have a default value that you use when the user didn't navigate from home/coupons to coupons since history.location.search doesn't have anything or you reconfigure your Route to use Router param where in instead of query your specify your Route like

<Route
   exact
   path="/coupons/:id"
   component={Coupon.Show}
/>

and use it like

 this.props.history.push({
      pathname: `/coupons/${id}`,
 })

or else if the coupon isn't received you can redirect the user to the home/coupons route

Upvotes: 1

ThatCoderGuy
ThatCoderGuy

Reputation: 677

Looking at your implementation, I would assume that you're using either react-router or reach-router ?

If so, in my experience I tend to use route props to specify that an ID should be expected.

I would usually setup a route for the index and a route for showing an object and a default route for no matches (think of that like a 404) like so:

 <Route
   exact
   path="/coupons"
   component={Coupon.Index}
 />
<Route
   exact
   path="/coupons/:id"
   component={Coupon.Show}
/>
<Route component={NoMatch} />

Specifying the "exact" prop ensures that it'll only render that component when the path matches correctly, so if you dont want an index route, you could omit it completely and when you navigate to that it'll fall back to the NoMatch component

The example I provided would change how it looks in the address bar for a more RESTful looking approach so instead of

http://localhost:3000/coupons?id=6 it would be http://localhost:3000/coupons/6

In the show component you can then access the prop value by the name that you specify after the colon ":id" in your Show component, using the props provided by the router like so:

let { id } = this.props.match.params;

I hope this helps

Upvotes: 0

Related Questions