Obtention des paramètres de requête à partir du fragment de hachage react-router


112

J'utilise react et react-router pour mon application côté client. Je n'arrive pas à comprendre comment obtenir les paramètres de requête suivants à partir d'une URL comme:

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

Mes itinéraires ressemblent à ceci (le chemin est totalement faux je sais):

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

Mon itinéraire fonctionne bien, mais je ne sais pas comment formater le chemin pour obtenir les paramètres que je souhaite. J'apprécie toute aide à ce sujet!


J'ai regardé autour de moi et n'ai pu trouver que des exemples d'extraction de paramètres de chaîne de requête dans les composants, viagetCurrentQuery
Cory Danielson


Vous pouvez utiliser les willTransitionTocrochets sur votre gestionnaire. Il reçoit des paramètres de chaîne de requête. github.com/rackt/react-router/commit/…
Cory Danielson

Aussi ici pour les documents sur les hooks de transition: github.com/rackt/react-router/blob/master/docs/api/components / ... Vous devriez répondre à cette question avec votre solution une fois que vous l'avez trouvée. Je suis sûr que vous ne serez pas la dernière personne à vous heurter à cette situation.
Cory Danielson

Réponses:


133

Remarque: copier / coller à partir du commentaire. Assurez-vous d'aimer le message original!

Ecrire en es6 et utiliser react 0.14.6 / react-router 2.0.0-rc5. J'utilise cette commande pour rechercher les paramètres de requête dans mes composants:

this.props.location.query

Il crée un hachage de tous les paramètres de requête disponibles dans l'URL.

Mettre à jour:

Pour React-Router v4, consultez cette réponse . En gros, utilisez this.props.location.searchpour obtenir la chaîne de requête et analyser avec le query-stringpackage ou URLSearchParams :

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');

2
Ce n'est plus le cas à partir de React-router 1.x puis 2.x ////
Peter Aron Zentai

7
Par Peter, cet exemple est obsolète: voir stackoverflow.com/a/35005474/298073
btown

2
querysemble avoir disparu dans React Router 4. github.com/ReactTraining/react-router/issues/…
Sung Cho

57

ANCIEN (avant v4):

Ecrire en es6 et utiliser react 0.14.6 / react-router 2.0.0-rc5. J'utilise cette commande pour rechercher les paramètres de requête dans mes composants:

this.props.location.query

Il crée un hachage de tous les paramètres de requête disponibles dans l'URL.

MISE À JOUR (React Router v4 +):

this.props.location.query dans React Router 4 a été supprimé (en utilisant actuellement la v4.1.1) plus d'informations sur le problème ici: https://github.com/ReactTraining/react-router/issues/4410

On dirait qu'ils veulent que vous utilisiez votre propre méthode pour analyser les paramètres de requête, en utilisant actuellement cette bibliothèque pour combler le vide: https://github.com/sindresorhus/query-string


2
J'ai testé avec React 0.14.8 et votre réponse ne fonctionne pas. Rendu: erreur TypeError: Cannot read property 'location' of undefined:: |
Thomas Modeneis

3
Hey @ThomasModeneis, est-ce le composant parent le plus élevé que votre routeur est en train de rendre? ou est-ce un composant enfant? Si je me souviens bien, vous devez passer this.props.location.query dans vos composants enfants à partir du composant parent que le routeur a rendu, la seule chose à laquelle je peux penser du haut de ma tête.
Marrs

55

Les réponses ci-dessus ne fonctionneront pas react-router v4. Voici ce que j'ai fait pour résoudre le problème -

Première installation de la chaîne de requête qui sera requise pour l'analyse.

npm install -save query-string

Maintenant, dans le composant routé, vous pouvez accéder à la chaîne de requête non analysée comme celle-ci

this.props.location.search

Vous pouvez le vérifier en vous connectant à la console.

Enfin analyser pour accéder aux paramètres de la requête

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

Donc, si la requête est comme ?hello=world

console.log(parsed.hello) va enregistrer world


16
Ou sans lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(besoin de polyfill pour les anciens navigateurs).
Ninh Pham

Cela devrait fonctionner lorsque je construis l'application, non?
Walter le

16

mise à jour 2017.12.25

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

URL comme

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

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

avec dépendance de chaîne de requête :

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

résultats:

2 {sort: "name"} home


"react-router": "^2.4.1"

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

const queryParams = this.props.location.query;

queryParams est un objet contenant les paramètres de requête: {name: novaline, age: 26}


Si vous avez quelque chose comme ceci: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(c'est-à-dire non /après #) Alors pour react router v4, vous devriez utiliser à la location.hashplace delocation.search
codeVerine

10

Avec le package stringquery:

import qs from "stringquery";

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

Avec le package de chaîne de requête:

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

Aucun paquet:

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

J'espère que cela pourra aider :)

Bon codage!


5
"react-router-dom": "^5.0.0",

vous n'avez pas besoin d'ajouter de module supplémentaire juste dans votre composant qui a une adresse URL comme celle-ci:

http: // localhost: 3000 / # /? autorité '

vous pouvez essayer le code simple suivant:

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

4

Après avoir lu les autres réponses (d'abord par @ duncan-finney puis par @Marrs), je me suis mis à trouver le journal des modifications qui explique la manière idiomatique react-router 2.x de résoudre ce problème. La documentation sur l'utilisation de l'emplacement (dont vous avez besoin pour les requêtes) dans les composants est en fait contredite par le code réel. Donc, si vous suivez leurs conseils, vous recevez de gros avertissements de colère comme celui-ci:

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

Il s'avère que vous ne pouvez pas avoir une propriété de contexte appelée location qui utilise le type d'emplacement. Mais vous pouvez utiliser une propriété de contexte appelée loc qui utilise le type d'emplacement. La solution est donc une petite modification sur leur source comme suit:

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

Vous pouvez également transmettre uniquement les parties de l'objet de localisation que vous souhaitez à vos enfants pour obtenir le même avantage. Cela n'a pas changé l'avertissement pour changer le type d'objet. J'espère que cela pourra aider.


1

Solution js simple:

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
}

Et vous pouvez l'appeler de n'importe où en utilisant:

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

J'espère que cela t'aides.


0

Vous pouvez obtenir l'erreur suivante lors de la création d'une version de production optimisée lors de l'utilisation du module de chaîne de requête .

Échec de la réduction du code de ce fichier: ./node_modules/query-string/index.js:8

Pour surmonter cela, veuillez utiliser le module alternatif appelé stringquery qui effectue bien le même processus sans aucun problème lors de l'exécution de la construction.

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.