Obtendo parâmetros de consulta do fragmento hash do roteador react


112

Estou usando o react e o react-router para a minha aplicação no lado do cliente. Não consigo descobrir como obter os seguintes parâmetros de consulta de um url como:

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

Minhas rotas são assim (o caminho está totalmente errado, eu sei):

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

Minha rota está funcionando bem, mas não tenho certeza de como formatar o caminho para obter os parâmetros que desejo. Agradeço qualquer ajuda nisto!


Eu olhei em volta e só consegui encontrar exemplos de extração de parâmetros de string de consulta dentro de componentes, viagetCurrentQuery
— Cory Danielson


Você pode usar os willTransitionToganchos em seu manipulador. Ele recebe parâmetros de string de consulta. github.com/rackt/react-router/commit/…
— Cory Danielson

Também aqui para documentos sobre os ganchos de transição: github.com/rackt/react-router/blob/master/docs/api/components/… Você deve responder a esta pergunta com sua solução assim que descobri-la. Tenho certeza de que você não será a última pessoa a se deparar com essa situação.
— Cory Danielson

Respostas:


133

Nota: Copiar / colar do comentário. Certifique-se de gostar da postagem original!

Escrevendo em es6 e usando react 0.14.6 / react-router 2.0.0-rc5. Eu uso este comando para pesquisar os parâmetros de consulta em meus componentes:

this.props.location.query

Ele cria um hash de todos os parâmetros de consulta disponíveis no url.

Atualizar:

Para React-Router v4, veja esta resposta . Basicamente, use this.props.location.searchpara obter a string de consulta e analisar com o query-stringpacote ou URLSearchParams :

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

2
Não é mais a maneira do React-router 1.x do que 2.x ////
— Peter Aron Zentai

7
De acordo com Peter, este exemplo está desatualizado: consulte stackoverflow.com/a/35005474/298073
— btown

2
queryparece ter sumido no React Router 4. github.com/ReactTraining/react-router/issues/…
— Sung Cho

57

OLD (pré v4):

Escrevendo em es6 e usando react 0.14.6 / react-router 2.0.0-rc5. Eu uso este comando para pesquisar os parâmetros de consulta em meus componentes:

this.props.location.query

Ele cria um hash de todos os parâmetros de consulta disponíveis no url.

ATUALIZAÇÃO (React Router v4 +):

this.props.location.query no React Router 4 foi removido (atualmente usando a v4.1.1) mais sobre o problema aqui: https://github.com/ReactTraining/react-router/issues/4410

Parece que eles querem que você use seu próprio método para analisar os parâmetros de consulta, atualmente usando esta biblioteca para preencher a lacuna: https://github.com/sindresorhus/query-string


2
Testei com React 0.14.8 e sua resposta não funciona renderizando: erro TypeError: Cannot read property 'location' of undefined:: |
— Thomas Modeneis

3
Ei @ThomasModeneis, este é o principal componente pai que seu roteador está renderizando? ou é um componente filho? Se bem me lembro, você tem que passar this.props.location.query em seus componentes filho do componente pai que o roteador renderizou, única coisa que eu consigo pensar de início.
— Marrs

55

As respostas acima não funcionarão em react-router v4. Aqui está o que fiz para resolver o problema -

Primeiro instale a string de consulta que será necessária para a análise.

npm install -save query-string

Agora, no componente roteado, você pode acessar a string de consulta não analisada como esta

this.props.location.search

Você pode fazer a verificação cruzada fazendo login no console.

Finalmente analise para acessar os 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 

Então, se a consulta for como ?hello=world

console.log(parsed.hello) logará world


16
Ou sem lib: const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(precisa de polyfill para navegadores mais antigos).
— Ninh Pham

Isso deve funcionar quando eu construir o aplicativo, certo?
— Walter

16

atualização 25/12/2017

"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

com dependência de string 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 é um objeto que contém os parâmetros de consulta: {name: novaline, age: 26}


Se você tiver algo assim: http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(ou seja, não /depois #) Então, para location.hashlocation.search
— react

10

Com pacote stringquery:

import qs from "stringquery";

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

Com pacote de string 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" } 

Sem pacote:

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 ajude :)

Boa codificação!


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

você não precisa adicionar nenhum módulo adicional apenas em seu componente que tenha um endereço de url como este:

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

você pode tentar o seguinte código simples:

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

4

Depois de ler as outras respostas (primeiro por @ duncan-finney e depois por @Marrs), comecei a procurar o log de alterações que explica a maneira idiomática react-router 2.x de resolver isso. A documentação sobre o uso de localização (que você precisa para consultas) em componentes é na verdade contradita pelo código real. Portanto, se você seguir o conselho deles, receberá grandes avisos de raiva como este:

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

Acontece que você não pode ter uma propriedade de contexto chamada local que usa o tipo de local. Mas você pode usar uma propriedade de contexto chamada loc que usa o tipo de local. Portanto, a solução é uma pequena modificação em sua fonte da seguinte forma:

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

Você também pode transmitir apenas as partes do objeto de localização que deseja que seus filhos tenham o mesmo benefício. Não mudou o aviso para mudar para o tipo de objeto. Espero que ajude.


1

Solução js simples:

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 você pode chamá-lo de qualquer lugar usando:

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

Espero que isto ajude.


0

Você pode obter o seguinte erro ao criar uma compilação de produção otimizada ao usar o módulo de string de consulta .

Falha ao reduzir o código deste arquivo: ./node_modules/query-string/index.js:8

Para superar isso, use o módulo alternativo chamado stringquery que faz o mesmo processo bem sem problemas durante a execução da compilação.

import querySearch from "stringquery";

var query = querySearch(this.props.location.search);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.