Obtener parámetros de consulta del fragmento hash react-router

112

Estoy usando react y react-router para mi aplicación en el lado del cliente. Parece que no puedo averiguar cómo obtener los siguientes parámetros de consulta de una URL como:

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

Mis rutas se ven así (el camino está totalmente equivocado, lo sé):

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

Mi ruta funciona bien, pero no estoy seguro de cómo formatear la ruta para obtener los parámetros que quiero. ¡Aprecio cualquier ayuda en esto!

Christopher Robin
fuente
Miré a mi alrededor y solo pude encontrar ejemplos de extracción de parámetros de cadena de consulta dentro de los componentes, a través degetCurrentQuery
Cory Danielson
Puede usar los willTransitionToganchos en su manejador. Recibe parámetros de cadena de consulta. github.com/rackt/react-router/commit/…
Cory Danielson
También aquí para obtener documentos sobre los ganchos de transición: github.com/rackt/react-router/blob/master/docs/api/components/… Debería responder a esta pregunta con su solución una vez que la haya descubierto. Estoy seguro de que no será la última persona en encontrarse con esta situación.
Cory Danielson

Respuestas:

133

Nota: copiar / pegar del comentario. ¡Asegúrate de que te guste la publicación original!

Escribiendo en es6 y usando react 0.14.6 / react-router 2.0.0-rc5. Utilizo este comando para buscar los parámetros de consulta en mis componentes:

this.props.location.query

Crea un hash de todos los parámetros de consulta disponibles en la URL.

Actualizar:

Para React-Router v4, consulte esta respuesta . Básicamente, utilice this.props.location.searchpara obtener la cadena de consulta y analizar con el query-stringpaquete o URLSearchParams :

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');
Duncan Finney
fuente
2
Ya no es la forma en que React-router 1.x luego 2.x ////
Peter Aron Zentai
7
Según Peter, este ejemplo no está actualizado: consulte stackoverflow.com/a/35005474/298073
btown
2
queryparece haber desaparecido en React Router 4. github.com/ReactTraining/react-router/issues/…
Sung Cho
57

ANTIGUO (anterior a v4):

Escribiendo en es6 y usando react 0.14.6 / react-router 2.0.0-rc5. Utilizo este comando para buscar los parámetros de consulta en mis componentes:

this.props.location.query

Crea un hash de todos los parámetros de consulta disponibles en la URL.

ACTUALIZAR (React Router v4 +):

this.props.location.query en React Router 4 se ha eliminado (actualmente usa v4.1.1) más sobre el problema aquí: https://github.com/ReactTraining/react-router/issues/4410

Parece que quieren que use su propio método para analizar los parámetros de consulta, actualmente usando esta biblioteca para llenar el vacío: https://github.com/sindresorhus/query-string

Marrs
fuente
2
Probé con React 0.14.8 y su respuesta no funciona renderizando: error TypeError: Cannot read property 'location' of undefined:: |
Thomas Modeneis
3
Hola @ThomasModeneis, ¿es este el componente principal más alto que está procesando su enrutador? o es un componente hijo? Si recuerdo correctamente, tienes que pasar this.props.location.query a tus componentes secundarios desde el componente principal que renderizó el enrutador, lo único que se me ocurre fuera de mi cabeza.
Marrs
55

Las respuestas anteriores no funcionarán en react-router v4 . Esto es lo que hice para resolver el problema:

Primero instale la cadena de consulta que será necesaria para el análisis.

npm install -save query-string

Ahora, en el componente enrutado puede acceder a la cadena de consulta sin analizar como esta

this.props.location.search

Puede verificarlo iniciando sesión en la consola.

Finalmente analizar para acceder a los parámetros de consulta

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

Entonces, si la consulta es como ?hello=world

console.log(parsed.hello) registrará world

hashcode55
fuente
16
O sin lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(necesita polyfill para navegadores más antiguos).
Ninh Pham
Esto debería funcionar cuando construyo la aplicación, ¿verdad?
Walter
16

actualización 2017.12.25

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

URL como

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

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

con dependencia de cadena de consulta :

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

resultados:

2 {sort: "name"} home


"react-router": "^2.4.1"

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

const queryParams = this.props.location.query;

queryParams es un objeto que contiene los parámetros de consulta: {name: novaline, age: 26}

diapositivasp2
fuente
Si tiene algo como esto: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(es decir, no /después #) Entonces, para react enrutador v4, debe usar en location.hashlugar delocation.search
codeVerine
10

Con el paquete stringquery:

import qs from "stringquery";

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

Con paquete de cadena de consulta:

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

Sin paquete:

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

Espero que ayude :)

¡Feliz codificación!

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

no necesita agregar ningún módulo adicional solo en su componente que tenga una dirección URL como esta:

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

puedes probar el siguiente código simple:

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

Después de leer las otras respuestas (primero por @ duncan-finney y luego por @Marrs) me dispuse a encontrar el registro de cambios que explica la forma idiomática react-router 2.x de resolver esto. La documentación sobre el uso de la ubicación (que necesita para las consultas) en los componentes en realidad se contradice con el código real. Entonces, si sigue sus consejos, recibirá grandes advertencias enojadas como esta:

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

Resulta que no puede tener una propiedad de contexto llamada ubicación que use el tipo de ubicación. Pero puede usar una propiedad de contexto llamada loc que usa el tipo de ubicación. Entonces, la solución es una pequeña modificación en su fuente de la siguiente manera:

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

También puede transmitir solo las partes del objeto de ubicación que desea que sus hijos obtengan el mismo beneficio. No cambió la advertencia para cambiar al tipo de objeto. Espero que ayude.

Adam McCormick
fuente
1

Solución 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
}

Y puedes llamarlo desde cualquier lugar usando:

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

Espero que esto ayude.

Vijesh Chandera
fuente
0

Puede obtener el siguiente error al crear una compilación de producción optimizada al usar el módulo de cadena de consulta .

No se pudo minimizar el código de este archivo: ./node_modules/query-string/index.js:8

Para superar esto, utilice el módulo alternativo llamado stringquery que hace bien el mismo proceso sin problemas mientras ejecuta la compilación.

import querySearch from "stringquery";

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