ChatGPT解决这个技术问题 Extra ChatGPT

Getting query parameters from react-router hash fragment

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!

I looked around and was only able to find examples of extracting query string parameters within components, via getCurrentQuery
You can use the willTransitionTo hooks on your handler. It receives query string parameters. github.com/rackt/react-router/commit/…
Also here for docs on the transition hooks: github.com/rackt/react-router/blob/master/docs/api/components/… 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.

C
Community

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');

It is no more the way as of React-router 1.x then 2.x ////
Per Peter, this example is out of date: see stackoverflow.com/a/35005474/298073
query seems to be gone in React Router 4. github.com/ReactTraining/react-router/issues/…
h
hashcode55

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


Or without lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello')); (need polyfill for older browsers).
This should work when I build the application, right?
M
Marrs

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


I've tested with React 0.14.8 and your answer does not work rendering: error: TypeError: Cannot read property 'location' of undefined :|
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.
s
slideshowp2

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}


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
M
Meisam Nazari
"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'); //

a
accimeesterlin

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!


A
Adam McCormick

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.


V
Vijesh Chandera

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.


B
Balasubramani M

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);