Abrufen von Abfrageparametern vom React-Router-Hash-Fragment

112

Ich verwende React und React-Router für meine Anwendung auf der Client-Seite. Ich kann anscheinend nicht herausfinden, wie die folgenden Abfrageparameter von einer URL wie der folgenden abgerufen werden können:

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

Meine Routen sehen so aus (der Weg ist völlig falsch, wie ich weiß):

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

Meine Route funktioniert einwandfrei, aber ich bin mir nicht sicher, wie ich den Pfad formatieren soll, um die gewünschten Parameter zu erhalten. Schätzen Sie jede Hilfe dazu!

Christopher Robin
quelle
Ich sah mich um und konnte nur Beispiele zum Extrahieren von Abfragezeichenfolgenparametern innerhalb von Komponenten übergetCurrentQuery
Cory Danielson
Sie können die willTransitionToHaken an Ihrem Handler verwenden. Es empfängt Abfragezeichenfolgenparameter. github.com/rackt/react-router/commit/…
Cory Danielson
Auch hier für Dokumente zu den Übergangshaken: github.com/rackt/react-router/blob/master/docs/api/components/… Sie sollten diese Frage mit Ihrer Lösung beantworten, sobald Sie es herausgefunden haben. Ich bin sicher, Sie werden nicht die letzte Person sein, die in diese Situation gerät.
Cory Danielson

Antworten:

132

Hinweis: Aus Kommentar kopieren / einfügen. Achten Sie darauf, den Originalbeitrag zu mögen!

Schreiben in es6 und Verwenden von react 0.14.6 / react-router 2.0.0-rc5. Ich verwende diesen Befehl, um die Abfrageparameter in meinen Komponenten nachzuschlagen:

this.props.location.query

Es wird ein Hash aller verfügbaren Abfrageparameter in der URL erstellt.

Aktualisieren:

Informationen zu React-Router v4 finden Sie in dieser Antwort . Verwenden Sie grundsätzlich, this.props.location.searchum die Abfragezeichenfolge abzurufen und mit dem query-stringPaket oder URLSearchParams zu analysieren :

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');
Duncan Finney
quelle
2
Es ist nicht mehr der Weg ab React-Router 1.x als 2.x ////
Peter Aron Zentai
7
Per Peter ist dieses Beispiel veraltet: siehe stackoverflow.com/a/35005474/298073
btown
2
queryscheint in React Router 4 verschwunden zu sein. github.com/ReactTraining/react-router/issues/…
Sung Cho
57

ALT (vor v4):

Schreiben in es6 und Verwenden von react 0.14.6 / react-router 2.0.0-rc5. Ich verwende diesen Befehl, um die Abfrageparameter in meinen Komponenten nachzuschlagen:

this.props.location.query

Es wird ein Hash aller verfügbaren Abfrageparameter in der URL erstellt.

UPDATE (React Router v4 +):

this.props.location.query in React Router 4 wurde entfernt (derzeit unter Verwendung von v4.1.1). Weitere Informationen zu diesem Problem finden Sie hier: https://github.com/ReactTraining/react-router/issues/4410

Sie möchten anscheinend, dass Sie Ihre eigene Methode verwenden, um die Abfrageparameter zu analysieren. Derzeit wird diese Bibliothek verwendet, um die Lücke zu schließen: https://github.com/sindresorhus/query-string

Marrs
quelle
2
Ich habe mit React 0.14.8 getestet und Ihre Antwort funktioniert nicht beim Rendern: Fehler :: TypeError: Cannot read property 'location' of undefined|
Thomas Modeneis
3
Hey @ThomasModeneis, ist dies die oberste übergeordnete Komponente, die Ihr Router rendert? oder ist es eine untergeordnete Komponente? Wenn ich mich richtig erinnere, müssen Sie diese.props.location.query von der übergeordneten Komponente, die der Router gerendert hat, an Ihre untergeordneten Komponenten übergeben, nur das, was ich mir vorstellen kann.
Marrs
55

Die obigen Antworten funktionieren nicht react-router v4. Folgendes habe ich getan, um das Problem zu lösen:

Zuerst installieren Abfrage-String , die für die Analyse benötigt wird.

npm install -save query-string

Jetzt können Sie in der gerouteten Komponente wie folgt auf die nicht analysierte Abfragezeichenfolge zugreifen

this.props.location.search

Sie können dies überprüfen, indem Sie sich in der Konsole anmelden.

Zum Schluss analysieren, um auf die Abfrageparameter zuzugreifen

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

Also, wenn Abfrage ist wie ?hello=world

console.log(parsed.hello) wird protokollieren world

Hashcode55
quelle
16
Oder ohne lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(brauche Polyfill für ältere Browser).
Ninh Pham
Das sollte funktionieren, wenn ich die Anwendung erstelle, oder?
Walter
16

Update 2017.12.25

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

URL wie

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

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

mit Abfragezeichenfolgenabhängigkeit :

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

Ergebnisse:

2 {sort: "name"} home


"react-router": "^2.4.1"

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

const queryParams = this.props.location.query;

queryParams ist ein Objekt, das die Abfrageparameter enthält: {name: novaline, age: 26}

Diashowp2
quelle
Wenn Sie so etwas haben: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(dh nicht /danach #) Dann sollten Sie location.hashfür location.search
React
10

Mit Stringquery-Paket:

import qs from "stringquery";

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

Mit Abfragezeichenfolge-Paket:

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

Kein Paket:

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

Hoffentlich hilft das :)

Viel Spaß beim Codieren!

EsterlingAccime Youtuber
quelle
5
"react-router-dom": "^5.0.0",

Sie müssen kein zusätzliches Modul nur in Ihrer Komponente hinzufügen, das eine URL-Adresse wie diese hat:

http: // localhost: 3000 / # /? Behörde '

Sie können den folgenden einfachen Code ausprobieren:

    const search =this.props.location.search;
    const params = new URLSearchParams(search);
    const authority = params.get('authority'); //
Meisam Nazari
quelle
4

Nachdem ich die anderen Antworten gelesen hatte (zuerst von @ duncan-finney und dann von @Marrs), machte ich mich auf die Suche nach dem Änderungsprotokoll, das den idiomatischen Reaktionsrouter 2.x erklärt, wie dies gelöst werden kann. Der Dokumentation zur Verwendung des Speicherorts (den Sie für Abfragen benötigen) in Komponenten widerspricht tatsächlich der tatsächliche Code. Wenn Sie also ihrem Rat folgen, erhalten Sie große wütende Warnungen wie diese:

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

Es stellt sich heraus, dass Sie keine Kontexteigenschaft namens location haben können, die den Standorttyp verwendet. Sie können jedoch eine Kontexteigenschaft namens loc verwenden, die den Standorttyp verwendet. Die Lösung ist also eine kleine Änderung an ihrer Quelle wie folgt:

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

Sie können auch nur die Teile des Standortobjekts weitergeben, die Sie für Ihre Kinder benötigen, um den gleichen Nutzen zu erzielen. Die Warnung wurde nicht geändert, um zum Objekttyp zu wechseln. Hoffentlich hilft das.

Adam McCormick
quelle
1

Einfache js Lösung:

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
}

Und Sie können es von überall aus aufrufen, indem Sie:

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

Hoffe das hilft.

Vijesh Chandera
quelle
0

Beim Erstellen eines optimierten Produktionsbuilds bei Verwendung des Abfragezeichenfolgenmoduls wird möglicherweise die folgende Fehlermeldung angezeigt .

Fehler beim Minimieren des Codes aus dieser Datei: ./node_modules/query-string/index.js:8

Um dies zu überwinden, verwenden Sie bitte das alternative Modul namens stringquery, das den gleichen Prozess ohne Probleme beim Ausführen des Builds gut ausführt .

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
Balasubramani M.
quelle