如何从查询字符串中获取参数值

时间:2016-02-12 00:19:13

标签: reactjs react-router

如何在我的routes.jsx文件中定义路由,以便从Twitter的服务器重定向后的单点登录过程中生成的URL中捕获__firebase_request_key参数值?

http://localhost:8000/#/signin?_k=v9ifuf&__firebase_request_key=blablabla

我尝试使用以下路由配置,但:redirectParam没有捕获所提到的参数:

<Router>
  <Route path="/" component={Main}>
    <Route path="signin" component={SignIn}>
      <Route path=":redirectParam" component={TwitterSsoButton} />
    </Route>
  </Route>
</Router>

39 个答案:

答案 0 :(得分:336)

React Router v3

React Router已经为您解析了该位置,并将其作为道具传递给您的RouteComponent。您可以通过

访问查询(在网址中?之后)
this.props.location.query.__firebase_request_key

如果您正在寻找路径参数值,在路由器内部用冒号(:)分隔,可以通过

访问
this.props.match.params.redirectParam

这适用于迟到的React Router v3版本(不确定哪个版本)。据报道较旧的路由器版本使用this.props.params.redirectParam

React Router v4和React Router v5

React Router v4不再为您解析查询,但您只能通过this.props.location.search访问它。有理由,请参阅nbeuchat's answer

E.g。将query-string库导入为qs即可

qs.parse(this.props.location.search, { ignoreQueryPrefix: true }).__firebase_request_key

有关解析搜索字符串的更多建议,请参阅this answer

此外,如果您的组件不是Switch的直接子组,则需要使用withRouter来访问任何路由器提供的道具。

常规

nizam.sp的建议

console.log(this.props)

在任何情况下都会有所帮助。

答案 1 :(得分:125)

React Router v4

使用component

<Route path="/users/:id" component={UserPage}/> 

this.props.match.params.id

使用路径道具自动渲染组件。


使用render

<Route path="/users/:id" render={(props) => <UserPage {...props} />}/> 

this.props.match.params.id

路线道具传递给渲染功能。

答案 2 :(得分:76)

React Router v3

使用React Router v3,您可以从this.props.location.search获取查询字符串(?qs1 = naisarg&amp; qs2 = parmar)。例如,使用let params = queryString.parse(this.props.location.search),会给{ qs1 : 'naisarg', qs2 : 'parmar'}

React Router v4

使用React Router v4,this.props.location.query不再存在。您需要改为使用 this.props.location.search 并自行解析查询参数或使用enter image description here等现有包。

示例

以下是使用React Router v4和query-string库的最小示例。

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

<强>理性

React Router团队合理删除query属性是:

  

有许多流行的包对查询字符串解析/字符串化略有不同,并且这些差异中的每一个对于某些用户可能是“正确”的方式而对于其他用户可能是“不正确的”。如果React Router选择了“正确的”,它只适合某些人。然后,它需要为其他用户添加一种替代其首选查询解析包的方法。 React Router没有内部使用搜索字符串来要求它解析键值对,所以它不需要选择其中哪一个应该是“正确的”。

     

[...]

     

4.0采用的方法是去除所有“包含电池”类型的功能,并回到基本路由。如果您需要查询字符串解析或异步加载或Redux集成或其他非常具体的内容,那么您可以使用专门针对您的用例的库添加它。您不需要的东西很少,您可以根据您的特定喜好和需求定制。

您可以在query-string找到完整的讨论。

答案 3 :(得分:58)

React Router v4不再具有 props.location.query 对象(请参阅github讨论)。因此,接受的答案不适用于较新的项目。

v4的解决方案是使用外部库query-string来解析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'}

答案 4 :(得分:31)

React Router 5.1 +

5.1引入了useLocationuseParams之类的各种钩子,可以在此处使用。

示例:

<Route path="/test/:slug" component={Dashboard} />

然后如果我们拜访说

http://localhost:3000/test/signin?_k=v9ifuf&__firebase_request_key=blablabla

您可以像检索

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

答案 5 :(得分:25)

使用这种单行代码,您可以使用纯JavaScript在React Hook和React Class Component中的任何地方使用它。

https://www.hunterisgod.com/?city=Leipzig

let city = (new URLSearchParams(window.location.search)).get("city")

答案 6 :(得分:23)

您可以查看react-router,简单来说,只要您在路由器中定义了代码,就可以使用代码获取查询参数:

Executor

答案 7 :(得分:20)

据我所知,您可以通过三种方法进行操作。

1。使用正则表达式获取查询字符串。

2。您可以使用浏览器api。 图片当前网址如下:

http://www.google.com.au?token=123

我们只想得到123;

第一

 const query = new URLSearchParams(this.props.location.search);

然后

const token = query.get('token')
console.log(token)//123

3。使用称为“查询字符串”的第三个库。 首先安装

npm i query-string

然后将其导入当前的javascript文件:

 import queryString from 'query-string'

下一步是在当前网址中获取“令牌”,请执行以下操作:

const value=queryString.parse(this.props.location.search);
const token=value.token;
console.log('token',token)//123

希望有帮助。

于25/02/2019更新

  1. 如果当前网址如下所示:

http://www.google.com.au?app=home&act=article&aid=160990

我们定义了一个获取参数的函数:

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

我们可以通过以下方式获得“援助”:

getQueryVariable('aid') //160990

答案 8 :(得分:15)

React Router v4

const urlParams = new URLSearchParams(this.props.location.search)
const key = urlParams.get('__firebase_request_key')

请注意,它目前是实验性的。

在此处检查浏览器兼容性:https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams#Browser_compatibility

答案 9 :(得分:14)

如果您的路由器是这样的

<Route exact path="/category/:id" component={ProductList}/>

你会得到像这样的身份

this.props.match.params.id

答案 10 :(得分:10)

使用React钩子时,无法访问 diff_time <dbl> 1 6 2 1.2 3 0.38 4 1 5 0.39 。 要捕获网址参数,请使用this.props.location对象。

window

答案 11 :(得分:9)

说有一个网址如下

http://localhost:3000/callback?code=6c3c9b39-de2f-3bf4-a542-3e77a64d3341

如果我们要从该URL中提取 code ,则下面的方法将起作用。

const authResult = new URLSearchParams(window.location.search); 
const code = authResult.get('code')

答案 12 :(得分:6)

this.props.params.your_param_name将有效。

这是从查询字符串中获取参数的方法。
console.log(this.props);探索所有可能性。

答案 13 :(得分:6)

从v4开始,

React router不再直接在query params对象中为您提供location。原因是

  

有很多流行的包可以查询字符串   解析/字符串化略有不同,以及每个   差异可能是某些用户的“正确”方式和“不正确”   为他人。如果React Router选择了“正确的”,它只会是   适合某些人。然后,它需要为其他人添加一种方式   用户在他们首选的查询解析包中替换。有   React Router不需要内部使用搜索字符串   解析键值对,因此不需要选择哪一个   其中一个应该是“正确的”。

包含它之后,只需在视图组件中解析期望查询对象的location.search就更有意义了。

您可以通过覆盖withRouter之类的react-router来一般性地执行此操作

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)

答案 14 :(得分:5)

如果您没有收到this.props ...您希望根据其他答案,则可能需要使用withRouterdocs 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))

答案 15 :(得分:5)

我很难解决这个问题。如果以上都不起作用,您可以尝试使用此方法。我正在使用create-react-app

要求

react-router-dom”:“ ^ 4.3.1”

解决方案

在指定路由器的位置

<Route path="some/path" ..../>

添加您想要这样传递的参数名称

<Route path="some/path/:id" .../>

在呈现某些/路径的页面上,您可以指定此名称以查看像这样的参数名称调用ID

componentDidMount(){
  console.log(this.props);
  console.log(this.props.match.params.id);
}

最后导出默认值

export default withRouter(Component);

记住要包含导入

import { withRouter } from 'react-router-dom'

当console.log(this.props)时,您将能够传递下来。玩得开心!

答案 16 :(得分:4)

React Router v5.1 引入了钩子:

对于

<Route path="/posts/:id">
  <BlogPost />
</Route>

您可以使用钩子访问参数/ id:

const { id } = useParams();

更多here

答案 17 :(得分:4)

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

答案 18 :(得分:4)

不是反应方式,但我相信此单行功能可以为您提供帮助:)

const getQueryParams = () => window.location.search.replace('?', '').split('&').reduce((r,e) => (r[e.split('=')[0]] = decodeURIComponent(e.split('=')[1]), r), {});

示例:
网址:...?a=1&b=c&d=test
代码:

>  getQueryParams()
<  {
     a: "1",
     b: "c",
     d: "test"
   }

答案 19 :(得分:4)

其实没有必要使用第三方库。我们可以用纯 JavaScript 来制作。

考虑以下 URL:

https://example.com?yourParamName=yourParamValue

现在我们得到:

const url = new URL(window.location.href);
const yourParamName = url.searchParams.get('yourParamName');

简而言之

const yourParamName = new URL(window.location.href).searchParams.get('yourParamName')

另一种智能解决方案(推荐)

const params = new URLSearchParams(window.location.search);
const yourParamName = params.get('yourParamName');

简而言之

const yourParamName = new URLSearchParams(window.location.search).get('yourParamName')

注意:

对于具有多个值的参数,使用“getAll”而不是“get”

https://example.com?yourParamName[]=yourParamValue1&yourParamName[]=yourParamValue2

const yourParamName = new URLSearchParams(window.location.search).getAll('yourParamName[]')

结果如下:

["yourParamValue1", "yourParamValue2"]

答案 20 :(得分:3)

在没有第三方库或复杂解决方案的情况下,只需一行即可完成所有操作。这是

let myVariable = new URLSearchParams(history.location.search).get('business');

您唯一需要更改的是带有您自己的参数名称的“业务”一词。

示例url.com?business=hello

myVariable的结果将是你好

答案 21 :(得分:3)

在使用react route dom时,将清空对象以进行匹配,但是如果您执行以下代码,则它将用于es6组件以及直接用于功能组件

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>

通过这种方式,您可以获得道具并匹配参数和配置文件ID

经过对es6组件的大量研究后,这对我有用。

答案 22 :(得分:2)

在您需要访问参数的组件中,您可以使用

this.props.location.state.from.search

将显示整个查询字符串(?符号后面的所有内容)

答案 23 :(得分:1)

也许有点晚了,但是这个反应钩子可以帮助您获取/设置URL查询中的值:https://github.com/rudyhuynh/use-url-search-params(由我编写)。

无论是否有react-router,它都可以工作。 下面是您的情况下的代码示例:

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

答案 24 :(得分:1)

也许是这样的东西?

Array1=Array ( [0] => 678 [1] => 137 [2] => 137 [3] => 128 [4] => 137 [5] => 137 [6] => 100 [7] => 137 [8] => 137 [9] => 137 )
Array2=Array ( [0] => 678 [1] => 137 [2] => 137 [3] => 128 [4] => 137 [5] => 137 [6] => 344 [7] => 137 [8] => 137 [9] => 137 )
Array3=Array ( [0] => 20 [3] => 30 [6] => 40 )

答案 25 :(得分:1)

在React Router v4中,只有路由是正确的

您可以通过withRouter高阶组件访问历史对象的属性和最接近的匹配项。 withRouter会在呈现时将更新的匹配,位置和历史道具传递给包装组件。

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)

https://reacttraining.com/react-router/web/api/withRouter

答案 26 :(得分:1)

您可以创建简单的钩子,以从当前位置提取搜索参数:

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
}

然后您可以在功能组件内部使用它,如下所示:

// 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'}

答案 27 :(得分:1)

也许有人可以帮助阐明原因,但是如果您尝试击中道具以从App.js页面上的全新安装的Create React App中找到位置,则会得到:

TypeError:无法读取未定义的属性“搜索”

即使我将App.js作为本地路由:

<Route exact path='/' render={props => (

仅在App.js上,使用window.location对我有用:

import queryString from 'query-string';
...
const queryStringParams = queryString.parse(window.location.search);

答案 28 :(得分:0)

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
}

答案 29 :(得分:0)

您可以使用以下反应钩子:

  1. 如果 url 发生变化,钩子状态会更新
  2. SSRtypeof window === "undefined",仅检查 window 会导致错误(尝试一下)
  3. Proxy 对象隐藏实现,因此返回 undefined 而不是 null

所以这是获取搜索参数作为对象的函数:

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
}

然后像这样使用它作为钩子:

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
}

如果您的网址如下所示:

/app?page=2&count=10

你可以这样阅读:

const { page, fields } = useQueryParams();

console.log(page, fields)

答案 30 :(得分:0)

在打字稿中,例如,请参见下面的代码段

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

react-router-dom反应,您可以

const {useLocation} from 'react-router-dom';
const s = useLocation().search;
const m = getQueryParams(s);

请参见下面的示例

// 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

答案 31 :(得分:0)

p.initSession = function(e, t, n) {
            return null == t && (t = e, e = null), 0 === g.value.length && e && (g.value = e, p.APIKEY = e), ge(e, t, n)
        };

答案 32 :(得分:0)

我使用了一个名为query-string的外部包来解析url参数。

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

答案 33 :(得分:-1)

您还可以使用react-location-query软件包,例如:

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

名称-获得价值 setName =设置值

此软件包有很多选项,请参见docs on Github

答案 34 :(得分:-1)

export class ClassName extends Component{
      constructor(props){
        super(props);
        this.state = {
          id:parseInt(props.match.params.id,10)
        }
    }
     render(){
        return(
          //Code
          {this.state.id}
        );
}

答案 35 :(得分:-1)

您可以使用以下方式查看查询:

console.log(this.props.location.query)

答案 36 :(得分:-2)

获取url参数的最简单方法是先检查所需组件中要接收的值。要调试此类问题,请在需要该参数的react钩子中添加调试器,比如说何时安装组件。

  componentDidMount() {
      debugger;
  }

使用调试器,您可以在控制台内部使用控制台中的此命令检查发送到该组件的道具。

this.props

它将为您提供如下输出对象:

{history: {…}, location: {…}, match: {…}, staticContext: undefined}

现在,您可以导航该对象以查找要搜索的内容,作为一个通用示例,可​​以从路由中定义为的URL获取参数ID

//to get id from the url : /products/:id
this.props.match.params.id

答案 37 :(得分:-3)

使用Axios进行GET请求的最简单方法是axios.get()函数。 Axios选项是axios.get()的第二个参数:Axios将序列化options.params并将其添加到查询字符串中,如下所示。

const axios = require('axios');

// Equivalent to `axios.get('https://httpbin.org/get?answer=42')`

const res = await axios.get('https://httpbin.org/get', { params: { answer: 42 } });

res.data.args; // { answer: 42 }

答案 38 :(得分:-3)

最简单的解决方案!

路由中的

   <Route path="/app/someUrl/:id" exact component={binder} />

在反应代码中:

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