Comment obtenir les paramètres de requête dans React-Router v4

87

J'utilise react-router-dom 4.0.0-beta.6 dans mon projet. J'ai un code comme suivant:

<Route exact path="/home" component={HomePage}/>

Et je veux obtenir des paramètres de requête dans le HomePagecomposant. J'ai trouvé location.searchparam, qui ressemble à ceci ?key=value:, donc il n'est pas analysé.

Quelle est la bonne façon d'obtenir les paramètres de requête avec react-router v4?

andrfas
la source

Réponses:

181

La capacité d'analyser les chaînes de requête a été supprimée de la V4 car il y a eu des demandes au fil des ans pour prendre en charge différentes implémentations. Sur ce, l'équipe a décidé qu'il serait préférable pour les utilisateurs de décider à quoi ressemblait cette implémentation. Nous vous recommandons d'importer une chaîne de requête lib. En voici un que j'utilise

const queryString = require('query-string');

const parsed = queryString.parse(props.location.search);

Vous pouvez également utiliser new URLSearchParamssi vous voulez quelque chose de natif et cela fonctionne pour vos besoins

const params = new URLSearchParams(props.location.search);
const foo = params.get('foo'); // bar

Vous pouvez en savoir plus sur la décision ici

Tyler McGinnis
la source
12
N'utilisez pas URLSearchParams sans polyfill. À partir de mars 2018, Googlebot utilise Chrome 41 ( développeurs.google.com /search/docs/guides/rendering) qui ne prend pas en charge URLSearchParams et votre application se cassera si elle est utilisée dans un chemin critique ( caniuse.com/#feat=urlsearchparams ).
Joshua Robinson
12

La réponse donnée est solide.

Si vous souhaitez utiliser le module qs au lieu de la chaîne de requête (leur popularité est à peu près égale), voici la syntaxe:

const query = qs.parse(props.location.search, {
  ignoreQueryPrefix: true
})

L' option ignoreQueryPrefix consiste à ignorer le point d'interrogation principal.

fisch2
la source
1
Agréable. en janvier 2019, qs compte 12 millions de téléchargements hebdomadaires contre 2,7 millions pour la chaîne de requête.
oyalhi
6

La réponse acceptée fonctionne bien, mais si vous ne souhaitez pas installer de package supplémentaire, vous pouvez utiliser ceci:

getUrlParameter = (name) => {
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    let regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    let results = regex.exec(window.location.search);
    return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
  };

Donné http://www.google.co.in/?key=value

getUrlParameter('key');

reviendra value

kartikag01
la source
Merci beaucoup, la bibliothèque "query-string" n'a pas fonctionné pour moi pour une raison quelconque, mais votre solution a fonctionné comme un charme. J'utilisais "react-dom": "^ 16.0.0", "react-router": "^ 4.2.0", "react-router-dom": "^ 4.2.2" et "query-string": "^ 5.0.1",
Rohan_Paul
cela suppose seulement que vous avez un seul paramètre dans votre chaîne de requête. L'OP demande clairement comment obtenir les paramètres de requête - et c'est ce que font les modules npm mentionnés. Transformez cela en une fonction qui renvoie un objet de paires clé / valeur à partir de la chaîne de requête et ce serait vraiment utile!
Andy Lorenz
@AndyLorenz cela fonctionne même lorsque vous avez plusieurs paramètres de requête, appelez la fonction donnée avec la clé dont vous souhaitez obtenir la valeur. Oui, la méthode peut également être transformée pour donner une carte des valeurs clés.
kartikag01
cela fonctionnerait mais pas une bonne solution @Kartik_Agarwal. (a) Cela nécessiterait plusieurs exécutions du même code (potentiellement coûteux), (b) des variables séparées devraient être utilisées pour chaque paramètre, alors qu'idéalement, vous rempliriez un objet de paires clé / valeur, (c) cela nécessite vous devez connaître vos noms de paramètres, et une vérification supplémentaire pour voir s'ils existent ou non. Si c'était mon code, je chercherais une regex capable de saisir tous les paramètres de manière itérative, mais je dois admettre que les regex font saigner mes oreilles!
Andy Lorenz
6

Une autre approche utile pourrait être d'utiliser le prêt à l'emploi URLSearchParamscomme celui-ci;

  let { search } = useLocation();

   const query = new URLSearchParams(search);
   const paramField = query.get('field');
   const paramValue = query.get('value');

Propre, lisible et ne nécessite pas de module. Plus d'informations ci-dessous;

user10750437
la source
5

Je faisais des recherches sur les paramètres pour React Router v4, et ils ne l'ont pas utilisé pour la v4, pas comme React Router v2 / 3. Je vais laisser une autre fonction - peut-être que quelqu'un la trouvera utile. Vous n'avez besoin que d'es6 ou de javascript brut.

function parseQueryParams(query) {
  //You get a '?key=asdfghjkl1234567890&val=123&val2&val3=other'
  const queryArray = query.split('?')[1].split('&');
  let queryParams = {};
  for (let i = 0; i < queryArray.length; i++) {
    const [key, val] = queryArray[i].split('=');
    queryParams[key] = val ? val : true;
  }
  /* queryParams = 
     {
      key:"asdfghjkl1234567890",
      val:"123",
      val2:true,
      val3:"other"
     }
  */
  return queryParams;
}

En outre, cette fonction peut être améliorée

Xopsie
la source
2

Hein?

queryfie(string){
    return string
        .slice(1)
        .split('&')
        .map(q => q.split('='))
        .reduce((a, c) => { a[c[0]] = c[1]; return a; }, {});
}

queryfie(this.props.location.search);
Faheem
la source
0

Je viens de faire cela, donc je n'ai pas besoin de modifier toute la structure du code (où vous utilisez la requête du magasin de routeur redux) si vous mettez à jour pour réagir au routeur v4 ou supérieur à partir d'une version inférieure.

https://github.com/saltas888/react-router-query-middleware

Dimitris Saltaferis
la source
1
Un lien vers une solution est le bienvenu, mais veuillez vous assurer que votre réponse est utile sans elle: ajoutez du contexte autour du lien afin que vos collègues utilisateurs aient une idée de ce que c'est et pourquoi il est là, puis citez la partie la plus pertinente de la page que vous '' relier au cas où la page cible ne serait pas disponible. Les réponses qui ne sont guère plus qu'un lien peuvent être supprimées .
mrun
0

Très facile

utilisez juste un crochet useParams()

Exemple:

Routeur :

<Route path="/user/:id" component={UserComponent} />

Dans votre composant :

export default function UserComponent() {

  const { id } = useParams();

  return (
    <>{id}</>
  );
}
CommonSenseCode
la source
Cela ne fonctionne pas pour le cas d'utilisation décrit dans la question (du moins pas avec React-Router v4: reactrouter.com/web/api/Hooks/useparams ) useParams expose uniquement les paramètres de chemin, pas les paramètres de recherche.
Bennit
-4

Sans besoin d'aucun paquet:

const params = JSON.parse(JSON.stringify(this.props.match.params));

Ensuite, vous pouvez accéder aux paramètres associés avec params.id

mesarikaya
la source
3
this.props.match.paramscontient des paramètres de chemin, cette question concerne les paramètres de requête.
Hubert