Recupero dei parametri di query dal frammento hash del router reattivo


112

Sto usando React e React-Router per la mia applicazione sul lato client. Non riesco a capire come ottenere i seguenti parametri di query da un URL come:

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

I miei percorsi assomigliano a questo (il percorso è totalmente sbagliato lo so):

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

Il mio percorso funziona correttamente ma non sono sicuro di come formattare il percorso per ottenere i parametri che desidero. Apprezzo qualsiasi aiuto su questo!


Mi sono guardato intorno e sono riuscito a trovare solo esempi di estrazione dei parametri della stringa di query all'interno dei componenti, tramitegetCurrentQuery
Cory Danielson,


Puoi usare i willTransitionToganci sul tuo handler. Riceve i parametri della stringa di query. github.com/rackt/react-router/commit/…
Cory Danielson

Anche qui per i documenti sugli hook di transizione: github.com/rackt/react-router/blob/master/docs/api/components/… Dovresti rispondere a questa domanda con la tua soluzione una volta che l'hai capito. Sono sicuro che non sarai l'ultima persona a imbattersi in questa situazione.
Cory Danielson

Risposte:


133

Nota: copia / incolla dal commento. Assicurati di apprezzare il post originale!

Scrivendo in es6 e utilizzando react 0.14.6 / react-router 2.0.0-rc5. Uso questo comando per cercare i parametri della query nei miei componenti:

this.props.location.query

Crea un hash di tutti i parametri di query disponibili nell'URL.

Aggiornare:

Per React-Router v4, vedi questa risposta . Fondamentalmente, usa this.props.location.searchper ottenere la stringa di query e analizza con il query-stringpacchetto o URLSearchParams :

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

2
Non è più il modo di React-router 1.x quindi 2.x ////
Peter Aron Zentai

7
Per Peter, questo esempio non è aggiornato: vedi stackoverflow.com/a/35005474/298073
BTown

2
querysembra essere andato in React Router 4. github.com/ReactTraining/react-router/issues/…
Sung Cho

57

VECCHIO (pre v4):

Scrivendo in es6 e utilizzando react 0.14.6 / react-router 2.0.0-rc5. Uso questo comando per cercare i parametri della query nei miei componenti:

this.props.location.query

Crea un hash di tutti i parametri di query disponibili nell'URL.

AGGIORNAMENTO (React Router v4 +):

this.props.location.query in React Router 4 è stato rimosso (attualmente utilizzando v4.1.1) ulteriori informazioni sul problema qui: https://github.com/ReactTraining/react-router/issues/4410

Sembra che vogliano che tu usi il tuo metodo per analizzare i parametri della query, attualmente utilizzando questa libreria per colmare il vuoto: https://github.com/sindresorhus/query-string


2
Ho provato con React 0.14.8 e la tua risposta non funziona rendering: errore TypeError: Cannot read property 'location' of undefined:: |
Thomas Modeneis

3
Ehi @ThomasModeneis, è questo il componente genitore più in alto che il tuo router sta renderizzando? o è un componente figlio? Se ricordo bene devi passare this.props.location.query nei componenti del tuo bambino dal componente genitore che il router ha reso, l'unica cosa a cui riesco a pensare fuori dalla mia testa.
Marrs

55

Le risposte di cui sopra non funzioneranno react-router v4. Ecco cosa ho fatto per risolvere il problema:

Prima stringa di query di installazione che sarà richiesta per l'analisi.

npm install -save query-string

Ora nel componente instradato puoi accedere alla stringa di query non analizzata come questa

this.props.location.search

Puoi effettuare un controllo incrociato accedendo alla console.

Infine analizza per accedere ai parametri della query

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

Quindi se la query è come ?hello=world

console.log(parsed.hello) registrerà world


16
O senza lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(serve polyfill per i browser meno recenti).
Ninh Pham

Dovrebbe funzionare quando creo l'applicazione, giusto?
Walter

16

aggiornamento 2017.12.25

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

URL come

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

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

con dipendenza dalla stringa di query :

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

i risultati:

2 {sort: "name"} home


"react-router": "^2.4.1"

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

const queryParams = this.props.location.query;

queryParams è un oggetto che contiene i parametri della query: {name: novaline, age: 26}


Se hai qualcosa del genere: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(cioè no /dopo #) Allora per location.hashlocation.search
React

10

Con pacchetto stringquery:

import qs from "stringquery";

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

Con pacchetto stringa di query:

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

Nessun pacchetto:

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

Spero che aiuti :)

Buona programmazione!


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

non è necessario aggiungere alcun modulo aggiuntivo solo nel componente che ha un indirizzo URL come questo:

http: // localhost: 3000 / # /? authority '

puoi provare il seguente semplice codice:

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

4

Dopo aver letto le altre risposte (prima di @ duncan-finney e poi di @Marrs) ho deciso di trovare il registro delle modifiche che spiega il modo idiomatico di reagire-router 2.x per risolvere questo problema. La documentazione sull'utilizzo della posizione (necessaria per le query) nei componenti è effettivamente contraddetta dal codice effettivo. Quindi, se segui i loro consigli, ricevi grossi avvertimenti arrabbiati come questo:

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

Risulta che non puoi avere una proprietà di contesto chiamata location che utilizza il tipo di posizione. Ma puoi usare una proprietà di contesto chiamata loc che usa il tipo di posizione. Quindi la soluzione è una piccola modifica sulla loro fonte come segue:

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

Puoi anche trasmettere solo le parti dell'oggetto di localizzazione che desideri ai tuoi figli per ottenere lo stesso vantaggio. Non ha modificato l'avviso per passare al tipo di oggetto. Spero che aiuti.


1

Soluzione js semplice:

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
}

E puoi chiamarlo da qualsiasi luogo utilizzando:

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

Spero che questo ti aiuti.


0

È possibile che venga visualizzato il seguente errore durante la creazione di una build di produzione ottimizzata quando si utilizza il modulo stringa di query .

Impossibile minimizzare il codice da questo file: ./node_modules/query-string/index.js:8

Per ovviare a questo problema, usa gentilmente il modulo alternativo chiamato stringquery che esegue bene lo stesso processo senza problemi durante l'esecuzione della build.

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.