1
resposta

Problemas com a Renderização SPA

Pessoal, boa tarde! Tudo certo?

Estou colocando um projeto em prática com os mesmos fundamentos deste curso. A intenção é fazer uma página específica para cada jogador, utilizando o useParams().

Porém, o problema que estou tendo é que, quando clicamos no { Link } (componente do React-Router-Dom} ele está inserido o path na Url da aplicação, porém não está renderizando, somente quando dou um refresh na página.

Só para entender melhor, o projeto que estou fazendo é sobre o meu time do coração (Internacional) onde existem, por enquanto, duas páginas: Principal e Plantel. Quando entamos na página plantel, é renderizado todos os jogadores do clube e quando clicado no jogador, é direcionado para uma página específica sobre ele (praticamente a mesma coisa que o Doguito com as notícias).

Seguem os códigos:

import { BrowserRouter, Route, Switch } from 'react-router-dom';

import Home from "./Pages/Home";
import './index.css';
import Rodape from './components/Rodape';
import Plantel from './Pages/Plantel';
import Cabecalho from './components/Cabecalho';
import Jogador from './Pages/Jogador';


function App() {
  return (
    <> 
      <BrowserRouter>
        <Cabecalho />  
        <Switch>           
          <Route exact path='/'>
            <Home />
          </Route>
          <Route exact path='/plantel'>
            <Plantel />
          </Route>
          <Route path={'/plantel/:id'}>
            <Jogador />
          </Route>
        </Switch>
      </BrowserRouter>
      <Rodape />
    </>
  );
}

export default App;

Todos os Links estão dentro da componente cabecalho que segue abaixo:

import { Link } from 'react-router-dom';

import adidas from '../../assets/imagens/logo-adidas.png';
import inter from '../../assets/imagens/logo-inter.png';

import { StyledHeader } from './styles';


function Cabecalho() {
    return (
        <StyledHeader>
            <figure>
                <Link to='/'>
                    <img src={inter} alt='escudo internacional' />
                </Link>
                <img src={adidas} alt='logo adidas' />
            </figure>

            <nav>
                <ul>
                    <li>
                        <Link to='/'>Página Principal</Link>
                    </li>
                    <li>
                        <Link to='/plantel'>Plantel</Link>
                    </li>
                    <li>
                        <Link to='/titulos'>Títulos</Link>
                    </li>
                </ul>
            </nav>
        </StyledHeader>
    );
}

export default Cabecalho;

Alguém já teve o mesmo erro e pode me ajudar? Abraços!!

1 resposta

Oi Pedro, tudo bem?

Desculpe a demora em retornar.

É comum encontrar problemas na renderização de Single Page Applications (SPAs) ao utilizar o React Router, mas vamos tentar solucionar o seu caso.

Pelo que pude entender, o problema é que ao clicar no Link para acessar a página do jogador, o path é inserido na URL, mas a página não é renderizada corretamente. Isso ocorre porque o React Router tenta atualizar apenas a parte da página que mudou, em vez de recarregar a página inteira. Então, quando você navega para a página do jogador, apenas a URL é atualizada, mas a página não é renderizada.

Para solucionar esse problema, é necessário fazer algumas alterações no código. Uma solução seria utilizar o hook useHistory ao invés do componente Link. Isso permitiria que a página fosse renderizada corretamente ao clicar no botão.

Segue um exemplo de como seria o código utilizando o hook useHistory:

import { BrowserRouter, Route, Switch, useHistory } from 'react-router-dom';

import Home from "./Pages/Home";
import './index.css';
import Rodape from './components/Rodape';
import Plantel from './Pages/Plantel';
import Cabecalho from './components/Cabecalho';
import Jogador from './Pages/Jogador';


function App() {
  const history = useHistory();

  return (
    <> 
      <BrowserRouter>
        <Cabecalho />  
        <Switch>           
          <Route exact path='/'>
            <Home />
          </Route>
          <Route exact path='/plantel'>
            <Plantel />
          </Route>
          <Route path={'/plantel/:id'}>
            <Jogador />
          </Route>
        </Switch>
      </BrowserRouter>
      <Rodape />
    </>
  );
}

export default App;

function Cabecalho() {
  const history = useHistory();

  return (
    <StyledHeader>
      <figure>
        <img src={inter} alt='escudo internacional' onClick={() => history.push('/')} />
        <img src={adidas} alt='logo adidas' />
      </figure>

      <nav>
        <ul>
          <li>
            <Link to='/'>Página Principal</Link>
          </li>
          <li>
            <Link to='/plantel'>Plantel</Link>
          </li>
          <li>
            <Link to='/titulos'>Títulos</Link>
          </li>
        </ul>
      </nav>
    </StyledHeader>
  );
}

export default Cabecalho;

No exemplo acima, o hook useHistory é importado do pacote react-router-dom e é utilizado para navegar para a página do jogador ao clicar na imagem do escudo do Internacional. Ao invés de utilizar o componente Link, foi utilizado um onClick na imagem, que chama a função history.push() e navega para a página desejada.

Espero que essa solução seja útil para você.

Um abraço e bons estudos.