Как получить значение параметра из строки запроса

215

Как я могу определить маршрут в файле routes.jsx для захвата значения параметра __firebase_request_key из URL-адреса, сгенерированного после однократного входа в Twitter после перенаправления с их серверов?

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>
  • 0
    Там в обсуждении Github здесь
Теги:
react-router

18 ответов

291
Лучший ответ

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 v4 больше не анализирует запрос, но вы можете получить доступ к нему только через this.props.location.search. По причинам см. Nbeuchat ответ.

Например, с помощью библиотеки строк запроса, импортированной как qs вы могли бы сделать

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

Кроме того, если ваш компонент не является прямым дочерним элементом Switch вам необходимо использовать withRouter для доступа к любому из предоставленных маршрутизатором реквизитов.

генеральный

предложение nizam.sp сделать

console.log(this.props)

будут полезны в любом случае.

  • 1
    Для этого не требуется менять реагирующий маршрутизатор.
  • 1
    Я бы не предложил использовать console.dir() из-за предупреждения ... по крайней мере :)
Показать ещё 7 комментариев
98

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 params текущего URL моего приложения в дочернем компоненте с использованием React Router v4. Если вы ищете параметры query params , this.props.location.query в React Router 4 был удален (в настоящее время используется v4.1.1). Смотрите этот ответ: stackoverflow.com/a/43630848/1508105
  • 18
    К сожалению, это не отвечает на этот вопрос, поскольку у вас не обязательно будет /users/?q=... но у вас может быть /user?q=... Вам следует использовать this.props.location.search в React Router v4 и проанализировать результаты самостоятельно, как описано в моем ответе ниже.
Показать ещё 2 комментария
53

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:

Существует несколько популярных пакетов, которые выполняют разбор/строчку строки запроса немного по-разному, и каждый из этих различий может быть "правильным" способом для некоторых пользователей и "неправильным" для других. Если React Router выбрал "правильный", это было бы правильно для некоторых людей. Затем ему нужно будет добавить способ для других пользователей заменить их в предпочтительный пакет синтаксического анализа запросов. Внутреннее использование строки поиска с помощью React Router не требует, чтобы он разбирал пары ключ-значение, поэтому нет необходимости выбирать, какой из них должен быть "правильным".

[...]

Подход, применяемый к 4.0, состоит в том, чтобы вырезать все функции, включенные в "батарейки", и вернуться к простой базовой маршрутизации. Если вам нужен синтаксический анализ строки запроса или асинхронная загрузка или интеграция с Redux или что-то еще очень конкретное, то вы можете добавить это с помощью библиотеки специально для вашего случая использования. Меньше трещины упакованы в то, что вам не нужно, и вы можете настроить вещи в соответствии с вашими предпочтениями и потребностями.

Вы можете найти полное обсуждение GitHub.

  • 1
    Работает отлично. Это должен быть принятый ответ по состоянию на лето 2018 года.
  • 1
    зачем вам вообще нужна библиотека, когда вы можете использовать URLSearchParams
Показать ещё 2 комментария
52

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'}
  • 1
    По какой-то причине для меня qs.parse приводит к: {'?foo': 'bar'}
  • 2
    @Chris var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true }); prefixed var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true }); должен это исправить. Пример найден здесь: github.com/ljharb/qs
23

вы можете проверить react-router, просто, вы можете использовать код для получения параметра запроса до тех пор, пока вы определили в своем маршрутизаторе:

this.props.params.userId
  • 19
    Это не правильный ответ в случае ОП. props.params предназначен для параметров URL (сегмент URL с префиксом «:» в реагирующем маршрутизаторе), props.location.query хранит параметры строки запроса (после «?») и является тем, что хочет OP.
14

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

  • 0
    Хорошее решение, но, к сожалению, IE не поддерживает ((
14

Если ваш маршрутизатор подобен этому

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

Вы получите этот id, подобный этому

this.props.match.params.id
10

Насколько я знаю, есть три способа сделать это.

1. использовать регулярное выражение для получения строки запроса.

2.Вы можете использовать браузер API. image текущий 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. использовать третью библиотеку под названием "строка запроса". Сначала установите его

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

Надеюсь, поможет.

5

React router from v4 on уже не дает вам параметры 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)
5

Если вы не получаете 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))
5

this.props.params.your_param_name будет работать.

Это способ получить параметры из строки запроса.
Прошу console.log(this.props); изучить все возможности.

4

Мне было трудно решить эту проблему. Если ни одна из вышеперечисленных задач вы не можете попробовать. Я использую приложение create-react-app

Требования

реакция-маршрутизатор-dom ":" ^ 4.3.1 "

Решение

В месте, где указан маршрутизатор

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

Добавьте имя параметра, которое вы хотите передать таким образом

<Route path="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
    И если вы используете TypeScript, не забудьте добавить RouteComponentProps<{id: number}>
  • 0
    куда вы добавляете RouteComponentProps <{id: number}> ??
2

В компоненте, где вам нужно получить доступ к параметрам, вы можете использовать

this.props.location.state.from.search

который покажет всю строку запроса (все после знака ?)

1

В React Router v4 только с Route является правильным способом

Вы можете получить доступ к свойствам объектов истории и ближайшему совпадению с помощью компонента более высокого порядка с Router. 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

0
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
    })
}
  • 0
    Добро пожаловать в стек переполнения! Пожалуйста, не отвечайте только с исходным кодом. Попробуйте дать хорошее описание того, как работает ваше решение. Смотрите: Как мне написать хороший ответ? , Спасибо
0

Вы можете увидеть запрос, используя:

console.log(this.props.location.query)
  • 1
    Это неверно Правильное значение это this.props.location.search
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}));
}
-4

самое простое решение!

в маршрутизации:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню