Vários nomes de caminho para um mesmo componente no roteador React

113

Estou usando o mesmo componente para três rotas diferentes:

<Router>
    <Route path="/home" component={Home} />
    <Route path="/users" component={Home} />
    <Route path="/widgets" component={Home} />
</Router>

Existe alguma maneira de combiná-lo, para ser como:

<Router>
    <Route path=["/home", "/users", "/widgets"] component={Home} />
</Router>
Chetan Garg
fonte
2
A partir do react-router 4.4.0, agora você pode especificar uma matriz de caminhos de uma maneira muito semelhante à sua sugestão. Veja minha resposta aqui .
Ben Smith

Respostas:

137

A partir do react -router v4.4.0-beta.4 e oficialmente da v5.0.0, agora você pode especificar uma matriz de caminhos que resolvem para um componente, por exemplo

<Router>
    <Route path={["/home", "/users", "/widgets"]} component={Home} />
</Router>

Cada caminho na matriz é uma string de expressão regular.

A documentação para esta abordagem pode ser encontrada aqui .

Ben Smith
fonte
5
Acredito que esta seja a melhor resposta. A resposta de @Cameron não suporta o recurso regexp completo de qualquer maneira (pelo menos eu não fui capaz de fazer isso).
Christopher Regner
2
Como faço para definir o exactatributo para um único caminho?
JulianSoto
1
@JulianSoto Crie uma rota para um componente com um único caminho junto com o caminho exato. Você pode então criar outra rota para o mesmo componente com uma matriz de caminhos sem o atributo exato.
Ben Smith
Não consigo yarn upgradede 4.3 a 4.4. Foi lançado oficialmente?
ndtreviv
@ndtreviv Olhando para o log de alteração do roteador react, posso ver que o recurso foi lançado na v4.4.0 Beta 4. Recomendo atualizar para a versão mais recente, que no momento em que este artigo foi escrito é a v5.5.0. Você pode fazer isso executando "yarn upgrade react-router --latest"
Ben Smith
115

Pelo menos com react-router v4, o pathpode ser uma string de expressão regular, então você pode fazer algo assim:

<Router>
    <Route path="/(home|users|widgets)/" component={Home} />
</Router>

Como você pode ver, é um pouco prolixo, então se o seu component/route for simples assim, provavelmente não vale a pena.

E, claro, se isso realmente acontecer com frequência, você sempre poderá criar um componente de agrupamento pathsque .mapaceite um parâmetro de matriz , que faz a regex ou lógica reutilizável.

Cameron
fonte
5
Ótima ideia @Cameron. Achei útil modificá-lo um pouco para corresponder apenas aos caminhos que começam com um dos grupos: /^\/(home|users|widgets)/ Agora, /widgetscorresponderá, mas /dashboard/widgetsnão corresponderá.
Towler
4
Deve ser ótimo, mas por enquanto o tipo regex não é válido na validação de prop-types: Warning: Failed prop type: Invalid prop path` do tipo regexpfornecido para Route, esperado string.`
Fábio Paiva
@ FábioPaiva sim, ainda não descobri como colocar um regex arbitrário na rota
Atav32
1
coloque-o como uma string<Route path="/(new|edit)/user/:id?" ... />
medv
2
não trabalhando compath={`/(${ROUTES.HOME}|${ROUTES.HOME_1})/`}
Murtaza Hussain
43

Não acho que seja se você usar uma versão do React Router anterior à v4.

Você pode usar um mapcomo faria com qualquer outro componente JSX, embora:

<Router>
    {["/home", "/users", "/widgets"].map((path, index) => 
        <Route path={path} component={Home} key={index} />
    )}
</Router>

EDITAR

Você também pode usar uma regex para o caminho no react-router v4 , desde que seja compatível com path-to-regexp . Veja a resposta de @Cameron para mais informações.

Christopher Chiche
fonte
3
Não se esqueça do keyadereço.
Neurotransmissor
9
note que isso causaria (indesejável ...?) remontagens ao alternar de caminhos (por exemplo, / home => / usuários naquele exemplo)
Hertzel Guinness
De fato! A conveniência provavelmente depende de seu caso de uso e de seus componentes. Se você não quiser remontar, usar regexp conforme indicado na minha edição pode funcionar melhor.
Christopher Chiche
5

A partir do react-route-dom v5.1.2, você pode passar vários caminhos conforme abaixo

 <Route path={"/home" | "/users" | "/widgets"} component={Home} />

E obviamente você precisa importar o arquivo Home jsx no topo.

Abhishek
fonte
4

Outra opção: use o prefixo da rota. /pagespor exemplo. Você vai ter

  • /pages/home
  • /pages/users
  • /pages/widgets

E então resolva de forma detalhada dentro do Homecomponente.

<Router>
  <Route path="/pages/" component={Home} />
</Router>
Arturtr
fonte
0

De acordo com a documentação do Roteador React, o 'caminho' do proptype é do tipo string. Portanto, não há como passar um array como props para o Componente de Rota.

Se a sua intenção é apenas alterar a rota, você pode usar o mesmo componente para uma rota diferente, sem problemas com isso

Vijaykrish93
fonte
1
Essa resposta não está mais correta, pois agora o caminho aceita uma matriz de string. Veja esta resposta .
Ben Smith
-1

A partir do react-router v4.4, você pode fazer algo assim abaixo.

armazene o caminho em uma variável e passe abaixo e use '|' Operador.

let home = "/home" ;
let users = "/users”;
let widgets = "/widgets" ;

<Route path={ {home} | {users} | {widgets} }  component={Home} /> 

então, para todos os caminhos correspondentes, ele renderizará o component={Home}que for de sua necessidade.

Nischith
fonte