How to get parameter value from query string?
ReactjsReact RouterReactjs Problem Overview
How can I define a route in my routes.jsx file to capture the __firebase_request_key
parameter value from a URL generated by Twitter's single sign on process after the redirect from their servers?
http://localhost:8000/#/signin?_k=v9ifuf&__firebase_request_key=blablabla
I tried with the following routes configuration, but the :redirectParam
is not catching the mentioned param:
<Router>
<Route path="/" component={Main}>
<Route path="signin" component={SignIn}>
<Route path=":redirectParam" component={TwitterSsoButton} />
</Route>
</Route>
</Router>
Reactjs Solutions
Solution 1 - Reactjs
React Router v6, using hooks
In react-router-dom v6 there's a new hook named useSearchParams. So with
const [searchParams, setSearchParams] = useSearchParams();
searchParams.get("__firebase_request_key")
you will get "blablabla"
. Note, that searchParams is an instance of URLSearchParams, which also implements an iterator, e.g. for using Object.fromEntries etc.
React Router v4/v5, without hooks, generic
React Router v4 does not parse the query for you any more, but you can only access it via this.props.location.search
(or useLocation, see below). For reasons see nbeuchat's answer.
E.g. with qs library imported as qs
you could do
qs.parse(this.props.location.search, { ignoreQueryPrefix: true }).__firebase_request_key
Another library would be query-string. See this answer for some more ideas on parsing the search string. If you do not need IE-compatibility you can also use
new URLSearchParams(this.props.location.search).get("__firebase_request_key")
For functional components you would replace this.props.location
with the hook useLocation. Note, you could use window.location.search
, but this won't allow to trigger React rendering on changes.
If your (non-functional) component is not a direct child of a Switch
you need to use withRouter to access any of the router provided props.
React Router v3
React Router already parses the location for you and passes it to your RouteComponent as props. You can access the query (after ? in the url) part via
this.props.location.query.__firebase_request_key
If you are looking for the path parameter values, separated with a colon (:) inside the router, these are accessible via
this.props.match.params.redirectParam
This applies to late React Router v3 versions (not sure which). Older router versions were reported to use this.props.params.redirectParam
.
General
nizam.sp's suggestion to do
console.log(this.props)
will be helpful in any case.
Solution 2 - Reactjs
React Router v4
Using component
<Route path="/users/:id" component={UserPage}/>
this.props.match.params.id
The component is automatically rendered with the route props.
Using render
<Route path="/users/:id" render={(props) => <UserPage {...props} />}/>
this.props.match.params.id
Route props are passed to the render function.
Solution 3 - Reactjs
React Router v3
With React Router v3, you can get query-string from this.props.location.search
(?qs1=naisarg&qs2=parmar
). For example, with let params = queryString.parse(this.props.location.search)
, would give { qs1 : 'naisarg', qs2 : 'parmar'}
React Router v4
With React Router v4, the this.props.location.query
does not exist anymore. You need to use this.props.location.search
instead and parse the query parameters either by yourself or using an existing package such as query-string
.
Example
Here is a minimal example using React Router v4 and the query-string
library.
import { withRouter } from 'react-router-dom';
import queryString from 'query-string';
class ActivateAccount extends Component{
someFunction(){
let params = queryString.parse(this.props.location.search)
...
}
...
}
export default withRouter(ActivateAccount);
Rational
The React Router's team rational for removing the query
property is:
> There are a number of popular packages that do query string parsing/stringifying slightly differently, and each of these differences might be the "correct" way for some users and "incorrect" for others. If React Router picked the "right" one, it would only be right for some people. Then, it would need to add a way for other users to substitute in their preferred query parsing package. There is no internal use of the search string by React Router that requires it to parse the key-value pairs, so it doesn't have a need to pick which one of these should be "right".
> [...]
> The approach being taken for 4.0 is to strip out all the "batteries included" kind of features and get back to just basic routing. If you need query string parsing or async loading or Redux integration or something else very specific, then you can add that in with a library specifically for your use case. Less cruft is packed in that you don't need and you can customize things to your specific preferences and needs.
You can find the full discussion on GitHub.
Solution 4 - Reactjs
As far as I know there are three methods you can do that.
1.use regular expression to get query string.
2.you can use the browser api. image the current url is like this:
http://www.google.com.au?token=123
we just want to get 123;
First
const query = new URLSearchParams(this.props.location.search);
Then
const token = query.get('token')
console.log(token)//123
3. use a third library called 'query-string'. First install it
npm i query-string
Then import it to the current javascript file:
import queryString from 'query-string'
Next step is to get 'token' in the current url, do the following:
const value=queryString.parse(this.props.location.search);
const token=value.token;
console.log('token',token)//123
Hope it helps.
Updated on 25/02/2019
if the current url looks like the following:
http://www.google.com.au?app=home&act=article&aid=160990
we define a function to get the parameters:
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
console.log(query)//"app=article&act=news_content&aid=160990"
var vars = query.split("&");
console.log(vars) //[ 'app=article', 'act=news_content', 'aid=160990' ]
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
console.log(pair)//[ 'app', 'article' ][ 'act', 'news_content' ][ 'aid', '160990' ]
if(pair[0] == variable){return pair[1];}
}
return(false);
}
We can get 'aid' by :
getQueryVariable('aid') //160990
Solution 5 - Reactjs
React Router v4 no longer has the props.location.query
object (see github discussion). So the accepted answer will not work for newer projects.
A solution for v4 is to use an outside library query-string to parse the props.location.search
const qs = require('query-string');
//or
import * as qs from 'query-string';
console.log(location.search);
//=> '?foo=bar'
const parsed = qs.parse(location.search);
console.log(parsed);
//=> {foo: 'bar'}
Solution 6 - Reactjs
When using React hooks there is no access to access to this.props.location
.
To capture url parameters use window
object.
const search = window.location.search;
const params = new URLSearchParams(search);
const foo = params.get('bar');
Solution 7 - Reactjs
React Router 5.1+
5.1 introduced various hooks like useLocation
and useParams
that could be of use here.
Example:
<Route path="/test/:slug" component={Dashboard} />
Then if we visited say
http://localhost:3000/test/signin?_k=v9ifuf&__firebase_request_key=blablabla
You could retrieve it like
import { useLocation } from 'react-router';
import queryString from 'query-string';
const Dashboard: React.FC = React.memo((props) => {
const location = useLocation();
console.log(queryString.parse(location.search));
// {__firebase_request_key: "blablabla", _k: "v9ifuf"}
...
return <p>Example</p>;
}
Solution 8 - Reactjs
With this one-liner, you can use it anywhere in both React Hook and React Class Component with plain JavaScript.
https://www.hunterisgod.com/?city=Leipzig
let city = (new URLSearchParams(window.location.search)).get("city")
Solution 9 - Reactjs
React Router v4
const urlParams = new URLSearchParams(this.props.location.search)
const key = urlParams.get('__firebase_request_key')
Please note that it is currently experimental.
Check browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams#Browser_compatibility
Solution 10 - Reactjs
http://localhost:8000/#/signin?id=12345
import React from "react";
import { useLocation } from "react-router-dom";
const MyComponent = () => {
const search = useLocation().search;
const id=new URLSearchParams(search).get("id");
console.log(id);//12345
}
Solution 11 - Reactjs
you can check the react-router, in simple,you can use the code to get query parameter as long as you defined in your router:
this.props.params.userId
Solution 12 - Reactjs
If your Router is like this
<Route exact path="/category/:id" component={ProductList}/>
You will get that id like this
this.props.match.params.id
Solution 13 - Reactjs
Not the react way, but I beleive that this one-line function can help you :)
const getQueryParams = (query = null) => (query||window.location.search.replace('?','')).split('&').map(e=>e.split('=').map(decodeURIComponent)).reduce((r,[k,v])=>(r[k]=v,r),{});
Example:
URL: ...?a=1&b=c&d=test
Code:
getQueryParams()
//=> {a: "1", b: "c", d: "test"}
getQueryParams('type=user&name=Jack&age=22')
//=> {type: "user", name: "Jack", age: "22" }
Solution 14 - Reactjs
Say there is a url as follows
> http://localhost:3000/callback?code=6c3c9b39-de2f-3bf4-a542-3e77a64d3341
If we want to extract the code from that URL, below method will work.
const authResult = new URLSearchParams(window.location.search);
const code = authResult.get('code')
Solution 15 - Reactjs
do it all in one line without 3rd party libraries or complicated solutions. Here is how
let myVariable = new URLSearchParams(history.location.search).get('business');
the only thing you need to change is the word 'business' with your own param name.
example url.com?business=hello
the result of myVariable will be hello
Solution 16 - Reactjs
function useQueryParams() {
const params = new URLSearchParams(
window ? window.location.search : {}
);
return new Proxy(params, {
get(target, prop) {
return target.get(prop)
},
});
}
React hooks are amazing
If your url looks like /users?page=2&count=10&fields=name,email,phone
// app.domain.com/users?page=2&count=10&fields=name,email,phone
const { page, fields, count, ...unknown } = useQueryParams();
console.log({ page, fields, count })
console.log({ unknown })
In case of your query parameter contains hyphone ("-") or space (" ")
then you can not unpack like { page, fields, count, ...unknown }
You'll need to go with treditional assignment like
// app.domain.com/users?utm-source=stackOverFlow
const params = useQueryParams();
console.log(params['utm-source']);
Solution 17 - Reactjs
If you aren't getting the this.props
... you were expecting based on the other answers, you may need to use withRouter
(docs v4):
import React from 'react'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router'
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}
render() {
const { match, location, history } = this.props
return (
<div>You are now at {location.pathname}</div>
)
}
}
// Create a new component that is "connected" (to borrow redux terminology) to the router.
const TwitterSsoButton = withRouter(ShowTheLocation)
// This gets around shouldComponentUpdate
withRouter(connect(...)(MyComponent))
// This does not
connect(...)(withRouter(MyComponent))
Solution 18 - Reactjs
I had a hard time solving this issue. If none of the above work you can try this instead. I am using the create-react-app
Requirements
react-router-dom": "^4.3.1"
Solution
At the location where router is specified
<Route path="some/path" ..../>
Add the parameter name that you would want to pass in like this
<Route path="some/path/:id" .../>
At the page where you are rendering some/path you can specify this to view the parameter name call id like this
componentDidMount(){
console.log(this.props);
console.log(this.props.match.params.id);
}
At the end where you export default
export default withRouter(Component);
Remember to include import
import { withRouter } from 'react-router-dom'
When console.log(this.props) you would be able what has been passed down. Have fun!
Solution 19 - Reactjs
React Router v5.1 introduced hooks:
For
<Route path="/posts/:id">
<BlogPost />
</Route>
You can access params / id with hook:
const { id } = useParams();
More here.
Solution 20 - Reactjs
React router
from v4 onwards no longer gives you the query params
directly in its location
object. The reason being
> There are a number of popular packages that do query string > parsing/stringifying slightly differently, and each of these > differences might be the "correct" way for some users and "incorrect" > for others. If React Router picked the "right" one, it would only be > right for some people. Then, it would need to add a way for other > users to substitute in their preferred query parsing package. There is > no internal use of the search string by React Router that requires it > to parse the key-value pairs, so it doesn't have a need to pick which > one of these should be "right".
Having included that, It would just make more sense to just parse location.search in your view components that are expecting a query object.
You can do this generically by overriding the withRouter
from react-router
like
customWithRouter.js
import { compose, withPropsOnChange } from 'recompose';
import { withRouter } from 'react-router';
import queryString from 'query-string';
const propsWithQuery = withPropsOnChange(
['location', 'match'],
({ location, match }) => {
return {
location: {
...location,
query: queryString.parse(location.search)
},
match
};
}
);
export default compose(withRouter, propsWithQuery)
Solution 21 - Reactjs
componentDidMount(){
//http://localhost:3000/service/anas
//<Route path="/service/:serviceName" component={Service} />
const {params} =this.props.match;
this.setState({
title: params.serviceName ,
content: data.Content
})
}
Solution 22 - Reactjs
Maybe a bit late but this react hook can help you get/set values in URL query: https://github.com/rudyhuynh/use-url-search-params (written by me).
It works with or without react-router
.
Below is code sample in your case:
import React from "react";
import { useUrlSearchParams } from "use-url-search-params";
const MyComponent = () => {
const [params, setParams] = useUrlSearchParams()
return (
<div>
__firebase_request_key: {params.__firebase_request_key}
</div>
)
}
Solution 23 - Reactjs
Actually there is no need to use 3rd party library. We can make with pure JavaScript.
consider the following URL:
https://example.com?yourParamName=yourParamValue
Now we get:
const url = new URL(window.location.href);
const yourParamName = url.searchParams.get('yourParamName');
In short
const yourParamName = new URL(window.location.href).searchParams.get('yourParamName')
Another Smart Solution (Recommended)
const params = new URLSearchParams(window.location.search);
const yourParamName = params.get('yourParamName');
In short
const yourParamName = new URLSearchParams(window.location.search).get('yourParamName')
NOTE:
use "getAll" instead of "get" for Params having multiple value
https://example.com?yourParamName[]=yourParamValue1&yourParamName[]=yourParamValue2
const yourParamName = new URLSearchParams(window.location.search).getAll('yourParamName[]')
Result will be like:
["yourParamValue1", "yourParamValue2"]
Solution 24 - Reactjs
You can use the following react hook:
- Hook state updates if the url changes
SSR
:typeof window === "undefined"
, just checkingwindow
causes errors (try it out)Proxy
object hides implementation, soundefined
is returned instead ofnull
So this is the function to get the search param as object:
const getSearchParams = <T extends object>(): Partial<T> => {
// server side rendering
if (typeof window === "undefined") {
return {}
}
const params = new URLSearchParams(window.location.search)
return new Proxy(params, {
get(target, prop, receiver) {
return target.get(prop as string) || undefined
},
}) as T
}
And then use it as hook like that:
const useSearchParams = <T extends object = any>(): Partial<T> => {
const [searchParams, setSearchParams] = useState(getSearchParams())
useEffect(() => {
setSearchParams(getSearchParams())
}, [typeof window === "undefined" ? "once" : window.location.search])
return searchParams
}
If your url looks like this:
/app?page=2&count=10
You can just read it like this:
const { page, count } = useQueryParams();
console.log(page, count)
Solution 25 - Reactjs
Try This
http://localhost:4000/#/amoos?id=101
// ReactJS
import React from "react";
import { useLocation } from "react-router-dom";
const MyComponent = () => {
const search = useLocation().search;
const id = new URLSearchParams(search).get("id");
console.log(id); //101
}
// VanillaJS
const id = window.location.search.split("=")[1];
console.log(id); //101
Solution 26 - Reactjs
this.props.params.your_param_name
will work.
This is the way to get the params from your query string.
Please do console.log(this.props);
to explore all the possibilities.
Solution 27 - Reactjs
You could create simple hook for extracting search params from current location:
import React from 'react';
import { useLocation } from 'react-router-dom';
export function useSearchParams<ParamNames extends string[]>(...parameterNames: ParamNames): Record<ParamNames[number], string | null> {
const { search } = useLocation();
return React.useMemo(() => { // recalculate only when 'search' or arguments changed
const searchParams = new URLSearchParams(search);
return parameterNames.reduce((accumulator, parameterName: ParamNames[number]) => {
accumulator[ parameterName ] = searchParams.get(parameterName);
return accumulator;
}, {} as Record<ParamNames[number], string | null>);
}, [ search, parameterNames.join(',') ]); // join for sake of reducing array of strings to simple, comparable string
}
then you could use it inside your functional component like this:
// current url: http://localhost:8000/#/signin?_k=v9ifuf&__firebase_request_key=blablabla
const { __firebase_request_key } = useSearchParams('__firebase_request_key');
// current url: http://localhost:3000/home?b=value
const searchParams = useSearchParameters('a', 'b'); // {a: null, b: 'value'}
Solution 28 - Reactjs
Maybe someone can help clarify why but if you're attempting to hit props to find location from a fresh install of Create React App on the App.js page you get:
> TypeError: Cannot read property 'search' of undefined
Even though I have App.js as the home route:
<Route exact path='/' render={props => (
On App.js only, using window.location worked for me:
import queryString from 'query-string';
...
const queryStringParams = queryString.parse(window.location.search);
Solution 29 - Reactjs
React Router v6
Source: Getting Query Strings (Search Params) in React Router
Use the new useSearchParams
hook and the .get()
method:
const Users = () => {
const [searchParams] = useSearchParams();
console.log(searchParams.get('sort')); // 'name'
return <div>Users</div>;
};
With this approach, you can read one or a few params.
BONUS Get params as an object:
If you need to get all query string params at once, then we can use Object.fromEntries
like this:
const Users = () => {
const [searchParams] = useSearchParams();
console.log(Object.fromEntries([...searchParams])); // ▶ { sort: 'name', order: 'asecnding' }
return <div>Users</div>;
};
Read more and live demo: Getting Query Strings (Search Params) in React Router
Solution 30 - Reactjs
In the component where you need to access the parameters you can use
this.props.location.state.from.search
which will reveal the whole query string (everything after the ?
sign)
Solution 31 - Reactjs
I used an external package called query-string to parse url parameter like so.
import React, {Component} from 'react'
import { parse } from 'query-string';
resetPass() {
const {password} = this.state;
this.setState({fetching: true, error: undefined});
const query = parse(location.search);
return fetch(settings.urls.update_password, {
method: 'POST',
headers: {'Content-Type': 'application/json', 'Authorization': query.token},
mode: 'cors',
body: JSON.stringify({password})
})
.then(response=>response.json())
.then(json=>{
if (json.error)
throw Error(json.error.message || 'Unknown fetch error');
this.setState({fetching: false, error: undefined, changePassword: true});
})
.catch(error=>this.setState({fetching: false, error: error.message}));
}
Solution 32 - Reactjs
When you work with react route dom then will empty object with for match but if you do the following code then it will for es6 component as well as it works directly for function component
import { Switch, Route, Link } from "react-router-dom";
<Route path="/profile" exact component={SelectProfile} />
<Route
path="/profile/:profileId"
render={props => {
return <Profile {...props} loading={this.state.loading} />;
}}
/>
</Switch>
</div>
This way you can get props and match params and profile id
This worked for me after a lot of research on es6 component.
Solution 33 - Reactjs
in typescript, see snippet below for example:
const getQueryParams = (s?: string): Map<string, string> => {
if (!s || typeof s !== 'string' || s.length < 2) {
return new Map();
}
const a: [string, string][] = s
.substr(1) // remove `?`
.split('&') // split by `&`
.map(x => {
const a = x.split('=');
return [a[0], a[1]];
}); // split by `=`
return new Map(a);
};
in react with react-router-dom
, you can do
const {useLocation} from 'react-router-dom';
const s = useLocation().search;
const m = getQueryParams(s);
see example below
// below is the transpiled and minified ts functions from above const getQueryParams=t=>{if(!t||"string"!=typeof t||t.length<2)return new Map;const r=t.substr(1).split("&").map(t=>{const r=t.split("=");return[r[0],r[1]]});return new Map(r)};
// an example query string
const s = '?arg1=value1&arg2=value2'
const m = getQueryParams(s)
console.log(m.get('arg1'))
console.log(m.get('arg2'))
console.log(m.get('arg3')) // does not exist, returns undefined
Solution 34 - Reactjs
In React Router v4 only withRoute is correct way
You can get access to the history object’s properties and the closest
import React from 'react'
import PropTypes from 'prop-types'
import { withRouter } from 'react-router'
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}
render() {
const { match, location, history } = this.props
return (
<div>You are now at {location.pathname}</div>
)
}
}
// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)
Solution 35 - Reactjs
Use let { redirectParam } = useParams();
for if you're using the functional component
It's a class component
constructor (props) {
super(props);
console.log(props);
console.log(props.match.params.redirectParam)
}
async componentDidMount(){
console.log(this.props.match.params.redirectParam)
}
Solution 36 - Reactjs
Or perhaps something like this?
let win = {
'location': {
'path': 'http://localhost:8000/#/signin?_k=v9ifuf&__firebase_request_key=blablabla'
}
}
if (win.location.path.match('__firebase_request_key').length) {
let key = win.location.path.split('__firebase_request_key=')[1]
console.log(key)
}
Solution 37 - Reactjs
You can use this simple hook written in Typescript
:
const useQueryParams = (query: string = null) => {
const result: Record<string, string> = {};
new URLSearchParams(query||window.location.search).forEach((value, key) => {
result[key] = value;
});
return result;
}
Usage:
// http://localhost:3000/?userId=1889&num=112
const { userId, num } = useQueryParams();
// OR
const params = useQueryParams('userId=1889&num=112');
Solution 38 - Reactjs
export class ClassName extends Component{
constructor(props){
super(props);
this.state = {
id:parseInt(props.match.params.id,10)
}
}
render(){
return(
//Code
{this.state.id}
);
}
Solution 39 - Reactjs
You also can use react-location-query package, example:
const [name, setName] = useLocationField("name", {
type: "string",
initial: "Rostyslav"
});
return (
<div className="App">
<h1>Hello {name}</h1>
<div>
<label>Change name: </label>
<input value={name} onChange={e => setName(e.target.value)} />
</div>
</div>
);
name - to get value setName = to set value
This package has many options, read more in docs on Github
Solution 40 - Reactjs
let data = new FormData();
data.append('file', values.file);
Solution 41 - Reactjs
most simple solution!
in routing :
<Route path="/app/someUrl/:id" exact component={binder} />
in react code :
componentDidMount() {
var id = window.location.href.split('/')[window.location.href.split('/').length - 1];
var queryString = "http://url/api/controller/" + id
$.getJSON(queryString)
.then(res => {
this.setState({ data: res });
});
}