133

I'm using react and react-router for my application on the client side. I can't seem to figure out how to get the following query parameters from a url like:

http://xmen.database/search#/?status=APPROVED&page=1&limit=20

My routes look like this (the path is totally wrong I know):

var routes = (
<Route>
    <DefaultRoute handler={SearchDisplay}/>
    <Route name="search" path="?status=:status&page=:page&limit=:limit" handler={SearchDisplay}/>
    <Route name="xmen" path="candidate/:accountId" handler={XmenDisplay}/>
</Route>
);

My route is working fine but I'm just not sure how to format the path to get the parameters I want. Appreciate any help on this!

Christopher Robin
  • 1,335
  • 2
  • 8
  • 5
  • I looked around and was only able to find examples of extracting query string parameters within components, via `getCurrentQuery` – Cory Danielson Apr 24 '15 at 17:28
  • https://github.com/rackt/react-router/issues/209 – Cory Danielson Apr 24 '15 at 17:29
  • You can use the `willTransitionTo` hooks on your handler. It receives query string parameters. https://github.com/rackt/react-router/commit/2a75f3ee9ea3f6eccd1c18e84747747bb72ebf38 – Cory Danielson Apr 24 '15 at 17:31
  • Also here for docs on the transition hooks: https://github.com/rackt/react-router/blob/master/docs/api/components/RouteHandler.md You should answer this question with your solution once you've figured it out. I'm sure you won't be the last person to bump into this situation. – Cory Danielson Apr 24 '15 at 17:34

10 Answers10

161

Note: Copy / Pasted from comment. Be sure to like the original post!

Writing in es6 and using react 0.14.6 / react-router 2.0.0-rc5. I use this command to lookup the query params in my components:

this.props.location.query

It creates a hash of all available query params in the url.

Update:

For React-Router v4, see this answer. Basically, use this.props.location.search to get the query string and parse with the query-string package or URLSearchParams:

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');
Community
  • 1
  • 1
Duncan Finney
  • 2,054
  • 1
  • 12
  • 15
62

The above answers won't work in react-router v4. Here's what I did to solve the problem -

First Install query-string which will be required for parsing.

npm install -save query-string

Now in the routed component you can access the un-parsed query string like this

this.props.location.search

You can cross check it by logging in the console.

Finally parse to access the query parameters

const queryString = require('query-string');
var parsed = queryString.parse(this.props.location.search);
console.log(parsed.param); // replace param with your own 

So if query is like ?hello=world

console.log(parsed.hello) will log world

hashcode55
  • 5,622
  • 4
  • 27
  • 40
  • 20
    Or without lib: `const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));` (need polyfill for older browsers). – ninhjs.dev Sep 06 '17 at 14:56
  • This should work when I build the application, right? –  Feb 28 '20 at 03:18
59

OLD (pre v4):

Writing in es6 and using react 0.14.6 / react-router 2.0.0-rc5. I use this command to lookup the query params in my components:

this.props.location.query

It creates a hash of all available query params in the url.

UPDATE (React Router v4+):

this.props.location.query in React Router 4 has been removed (currently using v4.1.1) more about the issue here: https://github.com/ReactTraining/react-router/issues/4410

Looks like they want you to use your own method to parse the query params, currently using this library to fill the gap: https://github.com/sindresorhus/query-string

Marrs
  • 706
  • 7
  • 10
  • 2
    I've tested with React 0.14.8 and your answer does not work rendering: error: `TypeError: Cannot read property 'location' of undefined` :| – Thomas Modeneis May 26 '16 at 07:48
  • 3
    Hey @ThomasModeneis, is this the topmost parent component that your router is rendering? or is it a child component? If i remember correctly you have to pass this.props.location.query into your child components from the parent component that the router rendered, only thing i can think of off the top of my head. – Marrs May 31 '16 at 19:33
17

update 2017.12.25

"react-router-dom": "^4.2.2"

url like

BrowserHistory: http://localhost:3000/demo-7/detail/2?sort=name

HashHistory: http://localhost:3000/demo-7/#/detail/2?sort=name

with query-string dependency:

this.id = props.match.params.id;
this.searchObj = queryString.parse(props.location.search);
this.from = props.location.state.from;

console.log(this.id, this.searchObj, this.from);

results:

2 {sort: "name"} home


"react-router": "^2.4.1"

Url like http://localhost:8080/react-router01/1?name=novaline&age=26

const queryParams = this.props.location.query;

queryParams is a object contains the query params: {name: novaline, age: 26}

Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • If you have something like this : `http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer` (ie no `/` after `#`) Then for react router v4 you should use `location.hash` instead of `location.search` – codeVerine Jul 23 '18 at 13:35
15
"react-router-dom": "^5.0.0",

you do not need to add any additional module, just in your component that has a url address like this:

http://localhost:3000/#/?authority'

you can try the following simple code:

    const search =this.props.location.search;
    const params = new URLSearchParams(search);
    const authority = params.get('authority'); //
Meisam Nazari
  • 904
  • 10
  • 18
10

With stringquery Package:

import qs from "stringquery";

const obj = qs("?status=APPROVED&page=1limit=20");  
// > { limit: "10", page:"1", status:"APPROVED" }

With query-string Package:

import qs from "query-string";
const obj = qs.parse(this.props.location.search);
console.log(obj.param); // { limit: "10", page:"1", status:"APPROVED" } 

No Package:

const convertToObject = (url) => {
  const arr = url.slice(1).split(/&|=/); // remove the "?", "&" and "="
  let params = {};

  for(let i = 0; i < arr.length; i += 2){
    const key = arr[i], value = arr[i + 1];
    params[key] = value ; // build the object = { limit: "10", page:"1", status:"APPROVED" }
  }
  return params;
};


const uri = this.props.location.search; // "?status=APPROVED&page=1&limit=20"

const obj = convertToObject(uri);

console.log(obj); // { limit: "10", page:"1", status:"APPROVED" }


// obj.status
// obj.page
// obj.limit

Hope that helps :)

Happy coding!

accimeesterlin
  • 4,528
  • 2
  • 25
  • 18
4

After reading the other answers (First by @duncan-finney and then by @Marrs) I set out to find the change log that explains the idiomatic react-router 2.x way of solving this. The documentation on using location (which you need for queries) in components is actually contradicted by the actual code. So if you follow their advice, you get big angry warnings like this:

Warning: [react-router] `context.location` is deprecated, please use a route component's `props.location` instead.

It turns out that you cannot have a context property called location that uses the location type. But you can use a context property called loc that uses the location type. So the solution is a small modification on their source as follows:

const RouteComponent = React.createClass({
    childContextTypes: {
        loc: PropTypes.location
    },

    getChildContext() {
        return { location: this.props.location }
    }
});

const ChildComponent = React.createClass({
    contextTypes: {
        loc: PropTypes.location
    },
    render() {
        console.log(this.context.loc);
        return(<div>this.context.loc.query</div>);
    }
});

You could also pass down only the parts of the location object you want in your children get the same benefit. It didn't change the warning to change to the object type. Hope that helps.

Adam McCormick
  • 1,654
  • 18
  • 22
3

Simple js solution:

queryStringParse = function(string) {
    let parsed = {}
    if(string != '') {
        string = string.substring(string.indexOf('?')+1)
        let p1 = string.split('&')
        p1.map(function(value) {
            let params = value.split('=')
            parsed[params[0]] = params[1]
        });
    }
    return parsed
}

And you can call it from anywhere using:

var params = this.queryStringParse(this.props.location.search);

Hope this helps.

Vijesh Chandera
  • 101
  • 1
  • 4
2
"react-router-dom": "6"

I could get the value of the page property by useSearchParams

let [searchParams, setSearchParams] = useSearchParams();

searchParams.get('page')

when you have a URL like http://asd.com/report/7?page=3 you can get the page . complete example is here :

 import React from 'react';
 import { useSearchParams} from "react-router-dom";
    
    const Detail = (props) => {
        const [searchParams, setSearchParams] = useSearchParams();
        console.log('page from search',searchParams.get('page')) // 1
        return (
            <div></div>
        );
    };
    
    export default Detail;

reactrouter

Samira
  • 2,361
  • 1
  • 12
  • 21
0

You may get the following error while creating an optimized production build when using query-string module.

Failed to minify the code from this file: ./node_modules/query-string/index.js:8

To overcome this, kindly use the alternative module called stringquery which does the same process well without any issues while running the build.

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
Balasubramani M
  • 7,742
  • 2
  • 45
  • 47