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

How to get parameter value from query string?

如何在我的 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>

this.props.params.your_param_name 可以。

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

React Router v6,使用 hooks

在 react-router-dom v6 中有一个名为 useSearchParams 的新钩子。所以用

const [searchParams, setSearchParams] = useSearchParams();
searchParams.get("__firebase_request_key")

你会得到"blablabla"。请注意,searchParams 是 URLSearchParams 的一个实例,它还实现了一个迭代器,例如使用 Object.fromEntries 等

React Router v4/v5,没有钩子,通用

React Router v4 不再为您解析查询,但您只能通过 this.props.location.search(或 useLocation,见下文)访问它。原因见 .

例如将 qs 库导入为 qs 你可以做

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

另一个库是 query-string. See for some more ideas on parsing the search string. If you do not need IE-compatibility 你也可以使用

new URLSearchParams(this.props.location.search).get("__firebase_request_key")

对于功能组件,您可以将 this.props.location 替换为挂钩 useLocation。请注意,您可以使用 window.location.search,但这将不允许在更改时触发 React 渲染。 如果您的(非功能性)组件不是 Switch 的直接子组件,您需要使用 withRouter 来访问路由器提供的任何道具。

React Router v3

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

访问查询(在 url 中的 ? 之后)部分
this.props.location.query.__firebase_request_key

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

访问这些值
this.props.match.params.redirectParam

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

一般

nizam.sp的建议

console.log(this.props)

无论如何都会有帮助。

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

this.props.params.userId

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

this.props.location.state.from.search

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

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

路由道具被传递给渲染函数。

如果您没有得到 this.props... 您根据其他答案所期望的结果,您可能需要使用 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))

React Router v4 不再有 props.location.query object(参见 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'}

如果你的路由器是这样的

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

你会得到这样的id

this.props.match.params.id

React Router v3

使用 React Router v3,您可以从 this.props.location.search (?qs1=naisarg&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 并自行或使用现有包(例如 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 属性 的理由是:

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

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

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

您可以通过 withRouter higher-order 组件访问历史对象的属性和最接近的匹配项。 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

我使用了一个名为 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}));
}
从 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

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)

最简单的解决方案!

在路由中:

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

我很难解决这个问题。如果上述工作的 none 你可以试试这个。我正在使用 create-react-app

要求

react-router-dom": "^4.3.1"

解决方案

在指定路由器的位置

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

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

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

在你渲染的页面some/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)时,您将能够传递下来的东西。玩得开心!

据我所知,您可以使用三种方法。

1.use 获取查询字符串的正则表达式。

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

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'

下一步是在当前 url 中获取 'token',执行以下操作:

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

希望对您有所帮助。

更新于 25/02/2019

  1. 如果当前 url 如下所示:

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

我们可以通过 :

得到 'aid'
getQueryVariable('aid') //160990
let data = new FormData();
data.append('file', values.file);
export class ClassName extends Component{
      constructor(props){
        super(props);
        this.state = {
          id:parseInt(props.match.params.id,10)
        }
    }
     render(){
        return(
          //Code
          {this.state.id}
        );
}

可能有点晚了,但是这个反应钩子可以帮助你 get/set 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>
  )
}

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

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

或者可能是这样的?

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

当你使用 react 路由时 dom 然后将使用 for match 清空对象但是如果你执行以下代码那么它将用于 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 组件进行大量研究后,这对我有用。

反应路由器 5.1+

5.1 引入了各种挂钩,例如 useLocation and useParams,可以在这里使用。

示例:

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

有了这个单行代码,你可以在 React Hook 和 React Class Component 的任何地方使用它 JavaScript.

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

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

假设有一个url如下

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

如果我们想从 URL 中提取 代码 ,下面的方法将起作用。

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

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

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

React Router v5.1 引入的钩子:

为了

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

您可以使用 hook 访问 params / id:

const { id } = useParams();

更多here.

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

TypeError: Cannot read property 'search' of undefined

虽然我的家路线是App.js:

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

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

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

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

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

您也可以使用 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>
  );

name - 获取值 setName = 设置值

这个包有很多选项,阅读更多docs on Github

无需第 3 方库或复杂的解决方案,一行即可完成所有操作。方法如下

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

您唯一需要更改的是单词 'business' 和您自己的参数名称。

例子url.com?business=hello

myVariable 的结果将是 hello

不是反应方式,但我相信这个one-line函数可以帮助你:)

const getQueryParams = (query = null) => (query||window.location.search.replace('?','')).split('&').map(e=>e.split('=').map(decodeURIComponent)).reduce((r,[k,v])=>(r[k]=v,r),{});

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

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

getQueryParams('type=user&name=Jack&age=22')
//=> {type: "user", name: "Jack", age: "22" }
function useQueryParams() {
    const params = new URLSearchParams(
      window ? window.location.search : {}
    );

    return new Proxy(params, {
        get(target, prop) {
            return target.get(prop)
        },
    });
}

React hooks 很棒

如果你的 url 看起来像 /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 })

如果您的查询参数包含连音 ("-") 或 space (" ") 那么你不能像{ page, fields, count, ...unknown }

那样解压

你需要像

这样的传统作业
// app.domain.com/users?utm-source=Whosebug

const params = useQueryParams();

console.log(params['utm-source']);

其实没有必要使用第三方库。我们可以用纯 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"]

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

  1. 如果 url 发生变化,挂钩状态会更新
  2. SSR: typeof 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
}

如果您的 url 看起来像这样:

/app?page=2&count=10

你可以这样读:

const { page, count } = useQueryParams();

console.log(page, count)

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
}

如果您使用的是功能组件,请使用 let { redirectParam } = useParams();

这是一个 class 组件

constructor (props) {  
        super(props);
        console.log(props);
        console.log(props.match.params.redirectParam)
}
async componentDidMount(){ 
        console.log(this.props.match.params.redirectParam)
}

React Router v6

来源:Getting Query Strings (Search Params) in React Router

使用新的 useSearchParams 挂钩和 .get() 方法:

const Users = () => {
  const [searchParams] = useSearchParams();
  console.log(searchParams.get('sort')); // 'name'

  return <div>Users</div>;
};

通过这种方法,您可以读取一个或几个参数。

奖金获取参数作为对象:

如果您需要一次获取所有查询字符串参数,那么我们可以这样使用Object.fromEntries

const Users = () => {
  const [searchParams] = useSearchParams();
  console.log(Object.fromEntries([...searchParams])); // ▶ { sort: 'name', order: 'asecnding' }
  return <div>Users</div>;
};

阅读更多并进行现场演示:Getting Query Strings (Search Params) in React Router

试试这个

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

您可以使用 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;
}

用法:

// http://localhost:3000/?userId=1889&num=112
const { userId, num } = useQueryParams();
// OR
const params = useQueryParams('userId=1889&num=112');

在React-Router-Dom V5

function useQeury() {
 const [query, setQeury] = useState({});
 const search = useLocation().search.slice(1);

 useEffect(() => {
   setQeury(() => {
     const query = new URLSearchParams(search);
     const result = {};
     for (let [key, value] of query.entries()) {
       result[key] = value;
     }
     setQeury(result);
   }, [search]);
 }, [search, setQeury]);

 return { ...query };
}


// you can destruct query search like:
const {page , search} = useQuery()

// result
// {page : 1 , Search: "ABC"}