关于reactjs:React-如何从查询字符串中获取参数值

React - How to get parameter value from query string

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

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

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

1
2
3
4
5
6
7
<Router>
  <Route path="/" component={Main}>
    <Route path="signin" component={SignIn}>
      <Route path=":redirectParam" component={TwitterSsoButton} />
    </Route>
  </Route>
</Router>


反应路由器v3

React Router已经为您解析了位置并将其作为道具传递给RouteComponent。您可以通过访问查询(在URL中的?之后)部分

1
this.props.location.query.__firebase_request_key

如果要查找路径参数值(在路由器内部用冒号(:)分隔),则可以通过以下方式访问它们

1
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的答案。

例如。使用导入为qs的查询字符串库,您可以执行

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

有关解析搜索字符串的更多想法,请参见此答案。

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

一般

nizam.sp的建议

1
console.log(this.props)

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


反应路由器v4

使用component

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

1
this.props.match.params.id

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

使用render

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

1
this.props.match.params.id

路线道具将传递给render函数。


反应路由器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库的最小示例。

1
2
3
4
5
6
7
8
9
10
11
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属性的理由是:

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.

您可以在GitHub上找到完整的讨论。


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

v4的解决方案是使用外部库查询字符串来解析props.location.search

1
2
3
4
5
6
7
8
9
10
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'}


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

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

2.您可以使用浏览器api。
图片当前的URL是这样的:

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

我们只想得到123;

第一

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

然后

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

3.使用第三个名为"查询字符串"的库。
首先安装

1
npm i query-string

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

1
 import queryString from 'query-string'

下一步是在当前URL中获取"令牌",请执行以下操作:

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

希望能帮助到你。

于25/02/2019更新

  • 如果当前网址如下所示:
  • http://www.google.com.au?app=home&act=article&aid=160990

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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);
    }

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

    1
    getQueryVariable('aid') //160990

    反应路由器v4

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

    请注意,它目前处于实验阶段。

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


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

    1
    this.props.params.userId


    如果您的路由器是这样的

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

    你会得到这样的ID

    1
    this.props.match.params.id


    使用React钩子时,无法访问this.props.location
    要捕获url参数,请使用window对象。

    1
    2
    3
    const search = window.location.search;
    const params = new URLSearchParams(search);
    const foo = params.get('bar');


    如果您没有得到this.props ...,根据其他答案,您可能需要使用withRouter(docs v4):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    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 (
          You are now at {location.pathname}
        )
      }
    }

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

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

    要求

    react-router-dom":" ^ 4.3.1"

    在指定路由器的位置

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

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

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

    在呈现某些/路径的页面上,您可以指定此名称以查看参数名称的呼叫ID,如下所示

    1
    2
    3
    4
    componentDidMount(){
      console.log(this.props);
      console.log(this.props.match.params.id);
    }

    在导出默认值的最后

    1
    export default withRouter(Component);

    记住要包括进口

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

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


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

    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".

    包含了这一点之后,仅在需要查询对象的视图组件中解析location.search才有意义。

    您可以通过覆盖react-router中的withRouter

    customWithRouter.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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
        })
    }


    this.props.params.your_param_name将起作用。

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


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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import React from"react";
    import { useUrlSearchParams } from"use-url-search-params";

    const MyComponent = () => {
      const [params, setParams] = useUrlSearchParams()
      return (
       
          __firebase_request_key: {params.__firebase_request_key}
       
      )
    }

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

    this.props.location.state.from.search

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


    在React Router v4中,只有withRoute是正确的方法

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 (
          You are now at {location.pathname}
        )
      }
    }

    // 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
    2
    3
    4
    5
    6
    7
    8
    9
    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)
    }


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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}));
    }


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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>

    这样您就可以获取道具并匹配参数和配置文件ID

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


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

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


    1
    2
    let data = new FormData();
    data.append('file', values.file);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    export class ClassName extends Component{
          constructor(props){
            super(props);
            this.state = {
              id:parseInt(props.match.params.id,10)
            }
        }
         render(){
            return(
              //Code
              {this.state.id}
            );
    }

    最简单的解决方案!

    在路由中:

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

    在反应代码中:

    1
    2
    3
    4
    5
    6
    7
    8
    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 });
          });
      }