0

I am new to React and trying to render a page based on the name query like http://localhost:3000/show?name=james

So I initially added the Route as :

<BrowserRouter>
<Switch>    
<Route path='*' component={ErrorComponent} />} />
<Route path="show(/:name)" name="name" component={Show}></Route>
</Switch>
</BrowserRouter>

And then I tried to render the component Show like below:

import React, { Component } from 'react';
import queryString from 'query-string';
class Show extends Component {
  componentDidMount(){
    console.log(this.props.location.search);
    const values = queryString.parse(this.props.location.search);
    console.log(values.name);
  }


  render() {
    const { params } = this.props.match;
    return <div>
      <h4>About</h4>
      <p>This is About page.</p>
      {params.id ? <b>ID: {params.id}</b> : <i>ID is optional.</i>}
    </div>
  }
}

export default Show;

then when I try to show the page

http://localhost:3000/show?name=james

It always show 404. Not sure which part I am doing it wrong. Any help is appreciated. Also I am using react-router-dom 5.1.2 . Thanks.

2 Answers 2

2

EDIT: Can't believe I didn't notice this originally...

You need to put your path="*" route at the bottom of the Switch otherwise it'll match everything and anything below it won't even have a chance to match since Switches match only a single route. The description of making sure you have your route path set up correctly (below) is applicable as well, of course.

      <Switch>
        <Route path="/show/:name?" component={ShowRouteParam} />
        <Route path="*">ERROR 404</Route>
      </Switch>

https://codesandbox.io/s/elated-browser-d0sew?file=/src/App.js


The routes don't match query parameters.

"Please note: The RegExp returned by path-to-regexp is intended for use with pathnames or hostnames. It can not handle the query strings or fragments of a URL."

Depending on how you want to do it, you can either make the id an optional part of the route, or let it be a normal query parameters

Option 1:

<Route path="/show/:name?" component={Show}></Route>

component:

import React, { Component } from 'react';
import queryString from 'query-string';
class Show extends Component {
  componentDidMount(){
    console.log(this.props.location.search);
    const values = queryString.parse(this.props.location.search);
    console.log(values.name);
  }


  render() {
    const { params } = this.props.match;
    return <div>
      <h4>About</h4>
      <p>This is About page.</p>
      {params.name ? <b>ID: {params.name}</b> : <i>Name is optional.</i>}
    </div>
  }
}

export default Show;

Option 2:

<Route path="/show" component={Show}></Route>

component:

import React, { Component } from 'react';
import queryString from 'query-string';
class Show extends Component {
  componentDidMount(){
    console.log(this.props.location.search);
    const values = queryString.parse(this.props.location.search);
    console.log(values.name);
  }


  render() {
    const values = queryString.parse(this.props.location.search);
    return <div>
      <h4>About</h4>
      <p>This is About page.</p>
      {values.name ? <b>ID: {values.name}</b> : <i>Name is optional.</i>}
    </div>
  }
}

export default Show;

Working example: https://codesandbox.io/s/silent-rain-n61zs

Sign up to request clarification or add additional context in comments.

9 Comments

Hi Zachary thanks for your explanation but still after trying your 2 solutions it complains for a 404. Is it anything to do with route?
Okay, I fixed the error in this. We were missing the initial route / in the route path. I also included a working example on codesandbox. Hope this helps :)
I can understand the logic but when I try this in my App and call the browser with localhost:3000/show?name=james it should render the page right .but it is still 404 .And I am also using Browser router is that the case
@UsmanJ, I updated my answer as I realized I goofed a bit. If the update doesn't fix your issue, I'd really need to see a reproducible example to be able to assist.
@UsmanJ You need to have your query string separated into the search property of the to parameter: <Link to={pathname:'/a',search:'q=hi'} />. It seems that react router tries to assume that the pathname is in fact a path even if there are query params included in it. codesandbox.io/s/recursing-platform-q6ry7
|
1

path="show(/:name)"

This isn't a valid URL path to match on.

Redefine the path to ["/show/:id", "/show"]

<Route path={["/show/:id", "/show"]} name="name" component={Show} />

And since the Route is directly rendering the component, it can pull the query parameters and match parameters straight from props (this.props.match.params & this.props.location.search). Specifying two matching paths is equivalent to defining two separate Routes that render the same component. The same rules apply to path specificity, so define more complex matches first within the array.

class Show extends Component {
  componentDidMount(){
    console.log(this.props.location.search);
    const values = queryString.parse(this.props.location.search);
    console.log(values.name);
  }

  render() {
    const { params } = this.props.match;
    return <div>
      <h4>About</h4>
      <p>This is About page.</p>
      {params.id ? <b>ID: {params.id}</b> : <i>ID is optional.</i>}
    </div>
  }
}

Edit frosty-banach-9ou2q

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.