Em alguns casos, pouquissimos caso podemos precisar que uma determinada rota do react seja renderizada mesmo sem estar na url correta.

Busquei pr essa solução porque em uma aplicação que estava fazendo eu tinha duas telas: uma com a aplicação em si e outra com um iframe para uma aplicação de um terceiro, dependendo do evento que ocorresse na minha tela eu redirecionava para a tela do terceiro.

Até ai tudo bem eu configurei duas rotas uma para a minha aplicação e outra para um componente que so tinha o iframe da aplicação terceira, so que a aplicação terceira demorava muito para carregar, e quando carregava se o usuário voltasse para a minha aplicação o iframe morria e seria carregar tudo novamente caso o usuário decidisse voltar.

Então depois de procurar muito na internet cheguei ao seguinte código

import React from 'react';
import { Route, matchPath } from "react-router";
import { BrowserRouter } from "react-router-dom";

import App from './screens/App'
import Iframe from './screens/Iframe'


export default () => (
  <BrowserRouter>
    {/* Não use o <Switch> */}
      <WrapRoute path="/" component={App} />
      <WrapRoute exact path="/iframe" component={Iframe} />
  </BrowserRouter>
)

// Aqui vem a parte mais importante
function WrapRoute({path, exact, component: Component, ...rest}) {
  function render(props) {
    const match = matchPath(path, props.location.pathname, {path, exact})
    const display = match?.isExact
                    ? "block"
                    : "none"
    return (
      <div style={{display}}>
        <Component {...props} match={match} />
      </div>
    )
  }
  return (
    <Route render={render} {...rest} />
  )
}

Alguns pontos que vale a pena destacar:

  • A função matchPath é a responsável por verificar se a rota está correta ou não. Esta função é usada internamente pelo próprio Componente Route do react

  • O Componente Route aceita uma propriedade render como alternativa a propriedade component. Se quiser saber mais sobre a diferença das duas recomendo este post aqui, em Inglês.