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

问题描述 投票:265回答:21

如何在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>
reactjs react-router
21个回答
362
投票

反应路由器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

例如。用query-string库导入qs你可以做到

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

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

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

一般

nizam.sp的建议

console.log(this.props)

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


6
投票

从v4开始的React router不再直接在query params对象中给你location。原因是

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

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

你可以通过覆盖withRouterreact-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)

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

5
投票

我很难解决这个问题。如果没有上述工作,您可以尝试这样做。我正在使用create-react-app

要求

react-router-dom“:”^ 4.3.1“

在指定路由器的位置

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

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

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

在您渲染某些/ path的页面上,您可以指定此参数来查看参数名称调用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)你将能够传递下来的东西。玩得开心!


5
投票
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
    })
}

2
投票

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

this.props.location.state.from.search

这将揭示整个查询字符串(?标志后的所有内容)


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


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

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

0
投票
let data = new FormData();
data.append('file', values.file);

-1
投票

您可以使用以下命令查看查询:

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

129
投票

反应路由器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

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


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

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

82
投票

反应路由器v3

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

反应路由器v4

使用React Router v4,this.props.location.query不再存在。您需要使用this.props.location.search并自己解析查询参数或使用现有的包(如query-string)。

这是使用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集成或其他非常具体的内容,那么您可以使用专门针对您的用例的库添加它。您不需要的东西很少,您可以根据自己的喜好和需求定制东西。

你可以找到关于GitHub的完整讨论。


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

25
投票

据我所知,有三种方法可以做到。

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

2.您可以使用浏览器API。 image当前网址是这样的:

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.使用名为'query-string'的第三个库。首先安装它

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

22
投票

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

this.props.params.userId

15
投票

反应路由器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


14
投票

如果您的路由器是这样的

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

你会得到这样的id

this.props.match.params.id

6
投票

this.props.params.your_param_name将工作。

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

© www.soinside.com 2019 - 2024. All rights reserved.