Получение параметров запроса из хеш-фрагмента реактивного маршрутизатора

112

Я использую реагирующий и реагирующий маршрутизатор для своего приложения на стороне клиента. Я не могу понять, как получить следующие параметры запроса из URL-адреса, например:

http://xmen.database/search#/?status=APPROVED&page=1&limit=20

Мои маршруты выглядят так (я знаю, что путь совершенно неправильный):

var routes = (
<Route>
    <DefaultRoute handler={SearchDisplay}/>
    <Route name="search" path="?status=:status&page=:page&limit=:limit" handler={SearchDisplay}/>
    <Route name="xmen" path="candidate/:accountId" handler={XmenDisplay}/>
</Route>
);

Мой маршрут работает нормально, но я просто не уверен, как отформатировать путь, чтобы получить нужные мне параметры. Ценю любую помощь в этом!

Кристофер Робин
источник
Я огляделся и смог найти только примеры извлечения параметров строки запроса в компонентах черезgetCurrentQuery
Кори Дэниелсон
github.com/rackt/react-router/issues/209
Кори Дэниэлсон,
Вы можете использовать willTransitionToкрючки на рукоятке. Он получает параметры строки запроса. github.com/rackt/react-router/commit/…
Кори Дэниэлсон,
Также здесь можно найти документацию по перехватчикам перехода: github.com/rackt/react-router/blob/master/docs/api/components/… Вы должны ответить на этот вопрос своим решением, как только разберетесь с ним. Я уверен, что вы не будете последним, кто столкнется с этой ситуацией.
Кори Дэниелсон,

Ответы:

133

Примечание: скопировать / вставить из комментария. Обязательно лайкните оригинальный пост!

Написание на es6 и использование react 0.14.6 / react-router 2.0.0-rc5. Я использую эту команду для поиска параметров запроса в моих компонентах:

this.props.location.query

Он создает хеш всех доступных параметров запроса в URL-адресе.

Обновить:

Для React-Router v4 см. Этот ответ . В основном используйте this.props.location.searchдля получения строки запроса и анализа с помощью query-stringпакета или URLSearchParams :

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');
Дункан Финни
источник
2
Это больше не так, как с React-router 1.x, чем с 2.x ////
Питер Арон Зентаи 09
7
За Петра, этот пример из даты: см stackoverflow.com/a/35005474/298073
btown
2
queryпохоже, пропал в React Router 4. github.com/ReactTraining/react-router/issues/…
Sung Cho
57

СТАРЫЙ (до версии 4):

Написание на es6 и использование react 0.14.6 / react-router 2.0.0-rc5. Я использую эту команду для поиска параметров запроса в моих компонентах:

this.props.location.query

Он создает хеш всех доступных параметров запроса в URL-адресе.

ОБНОВЛЕНИЕ (React Router v4 +):

this.props.location.query в React Router 4 был удален (в настоящее время используется v4.1.1), подробнее о проблеме здесь: https://github.com/ReactTraining/react-router/issues/4410

Похоже, они хотят, чтобы вы использовали свой собственный метод для анализа параметров запроса, в настоящее время используя эту библиотеку, чтобы заполнить пробел: https://github.com/sindresorhus/query-string

Маррс
источник
2
Я тестировал React 0.14.8, и ваш ответ не работает при рендеринге: error TypeError: Cannot read property 'location' of undefined:: |
Thomas Modeneis
3
Привет, @ThomasModeneis, это самый верхний родительский компонент, который обрабатывает ваш маршрутизатор? или это дочерний компонент? Если я правильно помню, вы должны передать this.props.location.query своим дочерним компонентам из родительского компонента, который рендерил маршрутизатор, единственное, что я могу придумать в своей голове.
Marrs
55

Приведенные выше ответы не будут работать react-router v4. Вот что я сделал для решения проблемы -

Сначала установите строку запроса, которая потребуется для синтаксического анализа.

npm install -save query-string

Теперь в маршрутизируемом компоненте вы можете получить доступ к не проанализированной строке запроса следующим образом

this.props.location.search

Вы можете перепроверить это, войдя в консоль.

Наконец, проанализируйте, чтобы получить доступ к параметрам запроса

const queryString = require('query-string');
var parsed = queryString.parse(this.props.location.search);
console.log(parsed.param); // replace param with your own 

Итак, если запрос похож на ?hello=world

console.log(parsed.hello) будет регистрировать world

хэш-код55
источник
16
Или без lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(для старых браузеров нужен полифилл).
Нинь
Это должно работать, когда я создаю приложение, верно?
Уолтер
16

обновление 2017.12.25

"react-router-dom": "^4.2.2"

URL как

BrowserHistory: http://localhost:3000/demo-7/detail/2?sort=name

HashHistory: http://localhost:3000/demo-7/#/detail/2?sort=name

с зависимостью строки запроса :

this.id = props.match.params.id;
this.searchObj = queryString.parse(props.location.search);
this.from = props.location.state.from;

console.log(this.id, this.searchObj, this.from);

полученные результаты:

2 {sort: "name"} home


"react-router": "^2.4.1"

URL как http://localhost:8080/react-router01/1?name=novaline&age=26

const queryParams = this.props.location.query;

queryParams - это объект, содержащий параметры запроса: {name: novaline, age: 26}

slideshowp2
источник
Если у вас есть что-то вроде этого: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(т.е. нет /после #), тогда для реактивного маршрутизатора v4 вы должны использовать location.hashвместоlocation.search
codeVerine
10

С пакетом строкового запроса:

import qs from "stringquery";

const obj = qs("?status=APPROVED&page=1limit=20");  
// > { limit: "10", page:"1", status:"APPROVED" }

С пакетом строки запроса:

import qs from "query-string";
const obj = qs.parse(this.props.location.search);
console.log(obj.param); // { limit: "10", page:"1", status:"APPROVED" } 

Нет пакета:

const convertToObject = (url) => {
  const arr = url.slice(1).split(/&|=/); // remove the "?", "&" and "="
  let params = {};

  for(let i = 0; i < arr.length; i += 2){
    const key = arr[i], value = arr[i + 1];
    params[key] = value ; // build the object = { limit: "10", page:"1", status:"APPROVED" }
  }
  return params;
};


const uri = this.props.location.search; // "?status=APPROVED&page=1&limit=20"

const obj = convertToObject(uri);

console.log(obj); // { limit: "10", page:"1", status:"APPROVED" }


// obj.status
// obj.page
// obj.limit

Надеюсь, это поможет :)

Удачного кодирования!

Эстерлинг Аксим Ютубер
источник
5
"react-router-dom": "^5.0.0",

вам не нужно добавлять какой-либо дополнительный модуль только в свой компонент с таким URL-адресом:

http: // localhost: 3000 / # /? авторитет '

вы можете попробовать следующий простой код:

    const search =this.props.location.search;
    const params = new URLSearchParams(search);
    const authority = params.get('authority'); //
Мейсам Назари
источник
4

Прочитав другие ответы (сначала @ duncan-finney, а затем @Marrs), я решил найти журнал изменений, который объясняет идиоматический способ решения этой проблемы с помощью response-router 2.x. Документация по использованию местоположения (что вам нужно для запросов) в компонентах фактически противоречат фактическому коду. Поэтому, если вы последуете их совету, вы получите серьезные гневные предупреждения вроде этого:

Warning: [react-router] `context.location` is deprecated, please use a route component's `props.location` instead.

Оказывается, у вас не может быть свойства контекста с именем location, которое использует тип местоположения. Но вы можете использовать свойство контекста loc, которое использует тип местоположения. Таким образом, решение представляет собой небольшую модификацию их источника следующим образом:

const RouteComponent = React.createClass({
    childContextTypes: {
        loc: PropTypes.location
    },

    getChildContext() {
        return { location: this.props.location }
    }
});

const ChildComponent = React.createClass({
    contextTypes: {
        loc: PropTypes.location
    },
    render() {
        console.log(this.context.loc);
        return(<div>this.context.loc.query</div>);
    }
});

Вы также можете передать только те части объекта местоположения, которые хотите, чтобы ваши дети получили такое же преимущество. Предупреждение о смене типа объекта не изменилось. Надеюсь, это поможет.

Адам МакКормик
источник
1

Простое решение js:

queryStringParse = function(string) {
    let parsed = {}
    if(string != '') {
        string = string.substring(string.indexOf('?')+1)
        let p1 = string.split('&')
        p1.map(function(value) {
            let params = value.split('=')
            parsed[params[0]] = params[1]
        });
    }
    return parsed
}

И вы можете вызвать его откуда угодно, используя:

var params = this.queryStringParse(this.props.location.search);

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

Виджеш Чандера
источник
0

Вы можете получить следующую ошибку при создании оптимизированной производственной сборки при использовании модуля строки запроса .

Не удалось минимизировать код из этого файла: ./node_modules/query-string/index.js:8

Чтобы преодолеть это, используйте альтернативный модуль под названием stringquery, который хорошо выполняет тот же процесс без каких-либо проблем при запуске сборки.

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
Баласубрамани М
источник