React-クエリ文字列からパラメーター値を取得する方法


412

__firebase_request_keyサーバーからのリダイレクト後にTwitterのシングルサインオンプロセスによって生成されたURLからパラメーター値をキャプチャするために、routes.jsxファイルでルートを定義するにはどうすればよいですか?

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>


3
残念ながら、質問には「クエリ文字列」とありますが、実際には「urlパラメータ」について質問しています
SeanMC

6
query strings、 "VAR1 =ヴァル&var2の= val2の?" url paramters: "/写真/:企業ID /新しい"
Maddocks

回答:


484

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

React Router v4およびReact Router v5、汎用

React Router v4はクエリを解析しなくなりましたが、を介してのみアクセスできますthis.props.location.search。理由については、nbeuchatの回答を参照してください。

例えばあなたができるようにインポートされたqsライブラリを使っqs

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

別のライブラリはquery-stringです。検索文字列の解析に関するいくつかのアイデアについては、この回答を参照してください。IE互換性が必要ない場合は、

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

機能コンポーネントの場合はthis.props.location、フックuseLocationに置き換えます。注:を使用することもできますwindow.location.searchが、これでは変更時にReactレンダリングをトリガーできません。(機能しない)コンポーネントがの直接の子でないSwitch場合は、Routerで使用する必要があります場合は、を、ルーターが提供する小道具にアクセスする必要があります。

一般的な

nizam.spの提案

console.log(this.props)

いずれの場合も役立ちます。


3
対応ルーターを変更する必要はありません。
クリスチャン

2
警告ノートのconsole.dir()ために使用することはお勧めしません...少なくとも:)
boldnik '21

1
さて、一回中身を見るだけです。ブレークポイントを設定して、デバッガーでthis.propsを評価することもできます。今日では、console.logでもその仕事をします(少なくともChromeでは、そのように出力された値を展開できます)。console.logでさえ、本番環境では何も使用しません。
クリスチャン

1
@Christian私は単純なJavaScriptを使用することになりました。const path = window.location.pathname; URLを教えてください。その後、必要な方法で解析できます。これをReactコンポーネントのcomponentWillMountライフサイクルイベントに配置しました。
Sam

5
でこの作業をするためreact-router-domに使用withRouterしなければなりませんでした!
demonofthemist 2017年

188

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

ルートプロップはレンダー関数に渡されます。


1
query paramsReact Router v4を使用して、子コンポーネント内のアプリの現在のURLにアクセスするのと同様の問題がありました。を探している場合query params、React Router 4のthis.props.location.queryは削除されました(現在はv4.1.1を使用しています)。この回答を参照してください: stackoverflow.com/a/43630848/1508105
Alex Johnson

42
あなたは必ずしもありませんので、これは残念ながら、質問に答えていない/users/?q=...が、あなたが持っている可能性が/user?q=...this.props.location.search以下の私の回答で説明するように、React Router v4で使用し、結果を自分で解析する必要があります。
nbeuchat

これが正解です。this.props.location.search存在しません。
NickJ

@NickJ:React Routerのどのバージョンを使用していますか?
nbeuchat

126

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

合理的な

queryプロパティを削除するためのReact Routerのチーム合理性は次のとおりです。

クエリ文字列の解析/文字列化をわずかに異なる方法で行う人気のあるパッケージがいくつかあり、これらの違いのそれぞれは、一部のユーザーにとっては「正しい」方法であり、他のユーザーにとっては「正しくない」方法です。React Routerが「正しい」ものを選択した場合、それは一部の人にとってのみ正しいでしょう。次に、他のユーザーが自分の好みのクエリ解析パッケージを置き換える方法を追加する必要があります。キーと値のペアの解析を必要とするReact Routerによる検索文字列の内部使用はないため、どちらが「正しい」かを選択する必要はありません。

[...]

4.0で採用されているアプローチは、「バッテリーが含まれている」種類の機能をすべて取り除き、基本的なルーティングだけに戻ることです。クエリ文字列の解析、非同期読み込み、Reduxの統合など、非常に具体的なものが必要な場合は、ユースケース専用のライブラリを追加できます。不要な詰め物が少なく、特定の好みやニーズに合わせてカスタマイズできます。

完全なディスカッションはGitHubで見つけることができます。


1
完璧に動作します。これは2018
。– mmla

4
URLSearchParamsを使用できるときにlibが必要なのはなぜですか
SuperUberDuper

3
-なぜならエッジとiOSのSafariの@SuperUberDuper developer.mozilla.org/en-US/docs/Web/API/...
ブライアン・バーンズ

3
はい、ただしURLSearchParamsポリフィルを使用します
Anthony Manning-Franklin

67

私が知る限り、これを行うには3つの方法があります。

1.正規表現を使用してクエリ文字列を取得します。

2.ブラウザ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.「クエリ文字列」と呼ばれる3番目のライブラリを使用します。最初にインストールしてください

npm i query-string

次に、それを現在のJavaScriptファイルにインポートします。

 import queryString from 'query-string'

次のステップは、現在のURLで「トークン」を取得することです。以下を実行します。

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

それが役に立てば幸い。

2019年2月25日に更新

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

私たちは「援助」を得ることができます:

getQueryVariable('aid') //160990

URLSearchParamsはIEでサポートされていません(誰にでも関係がある場合:)
Christian

@Christian Typical IE
Trevor Wood

66

React Router v4には props.location.query オブジェクトがありませんgithubの説明を参照)。したがって、受け入れられた回答は新しいプロジェクトでは機能しません。

v4のソリューションは、外部ライブラリのクエリ文字列を使用して、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'}

1
私のためにいくつかの理由で結果をqs.parse:{'?foo': 'bar'}
クリス・

2
@Chris var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true });が修正するはずです。ここにある例:github.com/ljharb/qs
アランシャピラ

38

Reactフックを使用する場合、へのアクセス権はありませんthis.props.location。URLパラメータをキャプチャするには、windowオブジェクトを使用します。

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

1
これは素晴らしい答えです。ありがとうございました。
LukeVenter

同じ結果を得るには、ウィンドウオブジェクトの代わりに「react-router-dom」の「useLocation」を使用できます。
Chasmatu

1
URLSearchParamsは、IEでサポートされていないdeveloper.mozilla.org/en-US/docs/Web/API/URLSearchParams/...
マイケルFreidgeim

さらに、window.locationにアクセスしても、変更時にReactの再レンダリングをトリガーすることはできません。
クリスチャン

25

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


2
素晴らしい解決策ですが、残念ながらIEはサポートしていません((
Andrey Patseiko

@AndreyPatseiko github.com/WebReflection/url-search-paramsにポリフィルがあります
Earlee

23

ルーターで定義した限り、簡単にreact-routerをチェックして 、コードを使用してクエリパラメーターを取得できます。

this.props.params.userId

25
OPの場合、これは正しい答えではありません。props.paramsURLパラメータ(反応ルータでは「:」で始まるURLセグメント)用であり、props.location.queryクエリ文字列パラメータ(「?」の後ろ)を格納し、OPが必要とするものです。
MatthieuHarlé2017年

20

React Router 5.1以降

5.1はuseLocation、やなどのさまざまなフックを導入しました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>;
}

17

あなたのルーターがこのようなものなら

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

あなたはこのようなIDを取得します

this.props.match.params.id

誰もがこれがReact Router 5.0.1でどのように機能するか知っていますか?this.props.match.paramsは常に空です。
Mark A. Tagliaferro

2
@ MarkA.Tagliaferroプロップは、ルートによってレンダリングされているコンポーネントにのみアクセスできます。これがコンポーネントに当てはまらない場合は、withRouter HOCでコンポーネントをラップすることでアクセスできます。
ジミーロング

14

このワンライナーを使用すると、プレーンなJavaScriptを使用して、React HookとReact Class Componentの両方の任意の場所で使用できます。

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

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

11

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

8

私はこの問題を解決するのに苦労しました。上記のいずれも動作しない場合は、代わりにこれを試すことができます。私は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)の場合、何が受け渡されたかを確認できます。楽しんで!


2
TypeScriptを使用する場合は、忘れずに追加してくださいRouteComponentProps<{id: number}>
ThunderDev

1
RouteComponentProps <{id:number}>はどこに追加しますか?
Choco

タイプProps = RouteComponentProps <{id:number}>;
19

クラスMyClassはReact.PureComponent <Props>を拡張します{
pfeds

次に、componentDidMount(たとえば)で、const myId = this.props.match.params.id;
19

7

React routerv4以降query paramsでは、locationオブジェクトに直接アクセスできなくなりました。その理由は

クエリ文字列の解析/文字列化をわずかに異なる方法で行う人気のあるパッケージがいくつかあり、これらの違いのそれぞれは、一部のユーザーにとっては「正しい」方法であり、他のユーザーにとっては「正しくない」方法です。React Routerが「正しい」ものを選択した場合、それは一部の人にとってのみ正しいでしょう。次に、他のユーザーが自分の好みのクエリ解析パッケージを置き換える方法を追加する必要があります。キーと値のペアの解析を必要とするReact Routerによる検索文字列の内部使用はないため、どちらが「正しい」かを選択する必要はありません。

それが含まれていると、クエリオブジェクトを期待しているビューコンポーネントでlocation.searchを解析するだけの方が理にかなっています。

これを一般的に行うには、withRouterfromをオーバーライドします。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)

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

4
Stack Overflowへようこそ!ソースコードだけで答えないでください。ソリューションがどのように機能するかについて、わかりやすい説明を提供してください。参照:良い答えを書くにはどうすればよいですか?。おかげで
sɐunıɔןɐqɐp

1
おそらく「データ」を取得することは
un

6

少し遅いかもしれませんが、この反応フックは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>
  )
}

そのようなシンプルだが素晴らしいフックを提供してくれてありがとう!
chr1s

5

this.props.params.your_param_name 働くでしょう。

これは、クエリ文字列からパラメータを取得する方法です。すべての可能性を探るために行って
くださいconsole.log(this.props);


3

使用できるパラメーターにアクセスする必要があるコンポーネント

this.props.location.state.from.search

クエリ文字列全体(?記号の後のすべて)が表示されます



2

React Router v4では、Route with with onlyが正しい方法です

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


2

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

2

あなたが反応ルート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コンポーネントに関する多くの研究の後に私にとってうまくいきました。


1

それともこのようなものですか?

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


0

現在の場所から検索パラメーターを抽出するための単純なフックを作成できます。

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

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


-5

最も簡単な解決策!

ルーティングで:

   <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 });
      });
  }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.