Pobieranie parametrów zapytania z fragmentu skrótu reagującego-routera

112

Używam routera React i React dla mojej aplikacji po stronie klienta. Nie mogę dowiedzieć się, jak uzyskać następujące parametry zapytania z adresu URL, takiego jak:

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

Moje trasy wyglądają tak (ścieżka jest całkowicie błędna, wiem):

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

Moja trasa działa poprawnie, ale nie jestem pewien, jak sformatować ścieżkę, aby uzyskać żądane parametry. Doceń jakąkolwiek pomoc w tej sprawie!

Christopher Robin
źródło
Rozejrzałem się i udało mi się znaleźć tylko przykłady wyodrębniania parametrów ciągu zapytania w komponentach, za pośrednictwemgetCurrentQuery
Cory Danielson
Możesz użyć willTransitionTohaczyków na swoim handlerze. Otrzymuje parametry ciągu zapytania. github.com/rackt/react-router/commit/…
Cory Danielson
Również tutaj, aby zapoznać się z dokumentacją dotyczącą haków przejścia: github.com/rackt/react-router/blob/master/docs/api/components/ ... Po ustaleniu rozwiązania należy odpowiedzieć na to pytanie, podając swoje rozwiązanie. Jestem pewien, że nie będziesz ostatnią osobą, która wpadnie na tę sytuację.
Cory Danielson

Odpowiedzi:

133

Uwaga: Skopiuj / wklejono z komentarza. Pamiętaj, aby polubić oryginalny post!

Pisząc w es6 i korzystając z reaguj 0.14.6 / react-router 2.0.0-rc5. Używam tego polecenia, aby wyszukać parametry zapytania w moich komponentach:

this.props.location.query

Tworzy skrót wszystkich dostępnych parametrów zapytania w adresie URL.

Aktualizacja:

W przypadku React-Router v4 zobacz tę odpowiedź . Zasadniczo użyj, this.props.location.searchaby pobrać ciąg zapytania i przeanalizować query-stringpakiet lub URLSearchParams :

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');
Duncan Finney
źródło
2
To już nie jest sposób od React-router 1.x, a następnie 2.x ////
Peter Aron Zentai
7
Według Petera ten przykład jest nieaktualny: patrz stackoverflow.com/a/35005474/298073
btown
2
querywydaje się, że zniknął w React Router 4. github.com/ReactTraining/react-router/issues/…
Sung Cho
57

STARE (przed v4):

Pisząc w es6 i korzystając z reaguj 0.14.6 / react-router 2.0.0-rc5. Używam tego polecenia, aby wyszukać parametry zapytania w moich komponentach:

this.props.location.query

Tworzy skrót wszystkich dostępnych parametrów zapytania w adresie URL.

UPDATE (React Router v4 +):

this.props.location.query w React Router 4 zostało usunięte (obecnie używa v4.1.1) więcej o tym problemie tutaj: https://github.com/ReactTraining/react-router/issues/4410

Wygląda na to, że chcą, abyś użył własnej metody do przeanalizowania parametrów zapytania, obecnie używając tej biblioteki do wypełnienia luki: https://github.com/sindresorhus/query-string

Marrs
źródło
2
Testowałem z Reactem 0.14.8 i Twoja odpowiedź nie działa renderując: błąd TypeError: Cannot read property 'location' of undefined:: |
Thomas Modeneis
3
Hej @ThomasModeneis, czy to najwyższy element nadrzędny renderowany przez router? czy jest to składnik podrzędny? Jeśli dobrze pamiętam, musisz przekazać this.props.location.query do komponentów podrzędnych z komponentu nadrzędnego, który renderował router, jedyną rzeczą, o której przychodzi mi do głowy.
Marrs
55

Powyższe odpowiedzi nie będą działać react-router v4. Oto, co zrobiłem, aby rozwiązać problem -

Najpierw zainstaluj ciąg zapytania, który będzie wymagany do analizy.

npm install -save query-string

Teraz w komponencie routowanym możesz uzyskać dostęp do niepanowanego ciągu zapytania w ten sposób

this.props.location.search

Możesz to sprawdzić, logując się do konsoli.

Na koniec przeanalizuj, aby uzyskać dostęp do parametrów zapytania

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

Więc jeśli zapytanie jest podobne ?hello=world

console.log(parsed.hello) będzie logować world

hashcode55
źródło
16
Lub bez lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(potrzebny jest polyfill dla starszych przeglądarek).
Ninh Pham
To powinno zadziałać, gdy zbuduję aplikację, prawda?
Walter
16

aktualizacja 2017.12.25

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

URL jak

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

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

z zależnością od ciągu zapytania :

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

wyniki:

2 {sort: "name"} home


"react-router": "^2.4.1"

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

const queryParams = this.props.location.query;

queryParams to obiekt zawierający parametry zapytania: {name: novaline, age: 26}

pokaz slajdówp2
źródło
Jeśli masz coś takiego: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(tj. Nie /po #) Następnie do reagowania routera v4 powinieneś użyć location.hashzamiastlocation.search
codeVerine
10

Z pakietem stringquery:

import qs from "stringquery";

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

Z pakietem ciągu zapytania:

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

Brak pakietu:

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

Mam nadzieję, że to pomoże :)

Miłego kodowania!

EsterlingAccime Youtuber
źródło
5
"react-router-dom": "^5.0.0",

nie musisz dodawać żadnego dodatkowego modułu tylko w swoim komponencie, który ma taki adres url:

http: // localhost: 3000 / # /? Authority

możesz wypróbować następujący prosty kod:

    const search =this.props.location.search;
    const params = new URLSearchParams(search);
    const authority = params.get('authority'); //
Meisam Nazari
źródło
4

Po przeczytaniu innych odpowiedzi (najpierw @ duncan-finney, a następnie @Marrs) postanowiłem znaleźć dziennik zmian, który wyjaśnia idiomatyczny sposób rozwiązania tego problemu przez React-router 2.x. Dokumentacji na temat korzystania z lokalizacją (co jest potrzebne do zapytań) w komponentach jest rzeczywiście zaprzecza rzeczywistego kodu. Więc jeśli zastosujesz się do ich rady, otrzymasz duże gniewne ostrzeżenia, takie jak to:

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

Okazuje się, że nie możesz mieć właściwości kontekstu o nazwie lokalizacja, która używa typu lokalizacji. Możesz jednak użyć właściwości kontekstu o nazwie loc, która używa typu lokalizacji. Tak więc rozwiązaniem jest mała modyfikacja ich źródła w następujący sposób:

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

Możesz również przekazać tylko te części obiektu lokalizacji, które chcesz, aby Twoje dzieci miały takie same korzyści. Nie zmieniło ostrzeżenia o zmianie typu obiektu. Mam nadzieję, że to pomoże.

Adam McCormick
źródło
1

Proste rozwiązanie 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
}

I możesz zadzwonić z dowolnego miejsca za pomocą:

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

Mam nadzieję że to pomoże.

Vijesh Chandera
źródło
0

Podczas tworzenia zoptymalizowanej kompilacji produkcyjnej podczas korzystania z modułu ciągu zapytania może wystąpić następujący błąd .

Nie udało się zminimalizować kodu z tego pliku: ./node_modules/query-string/index.js:8

Aby temu zaradzić, uprzejmie użyj alternatywnego modułu o nazwie stringquery, który dobrze wykonuje ten sam proces bez żadnych problemów podczas uruchamiania kompilacji.

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
Balasubramani M
źródło