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!

Christopher Robin
fonte
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');
Duncan Finney
fonte
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

Marrs
fonte
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

hashcode55
fonte
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}

slideshowp2
fonte
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!

EsterlingAccime Youtuber
fonte
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'); //
Meisam Nazari
fonte
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.

Adam McCormick
fonte
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.

Vijesh Chandera
fonte
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);
Balasubramani M
fonte