DEV Community

Cover image for React Router: Scroll To Top na mudança de rota
Saymon Tavares
Saymon Tavares

Posted on

React Router: Scroll To Top na mudança de rota

Se você estiver usando o React Router Dom para navegação e roteamento em seu aplicativo React, terá que lidar com a restauração de rolagem por conta própria porque a biblioteca não envia mais o gerenciamento de rolagem padrão (costumava fornecer uma solução pronta para uso em o passado).

Por padrão, se você tiver uma página de conteúdo longa e, em seguida, navegar para outra página de conteúdo longa, você permanecerá rolado para baixo. Esse comportamento não faz muito sentido porque muitas pessoas não gostam de ler o texto de cabeça para baixo. O exemplo abaixo mostrará como rolar automaticamente para o topo da página em cada mudança de rota. Usaremos os hooks useEffect e useLocation para fazer o trabalho.

Atualizamos recentemente para funcionar com o React Router +6.x. No entanto, o trecho de código do React Router 5.x também está disponível.

O Componente

1 - Crie um novo projeto React e instale react-router-dom:

$ npm install react-router-dom@6 --save
Enter fullscreen mode Exit fullscreen mode

2 - Crie um componente wrapper que lide com a restauração de rolagem para você:

// ScrollToTop.tsx
import { useEffect } from "react"
import { useLocation, RoutesProps } from "react-router-dom"

export default function ScrollToTop (props: RoutesProps) {
  const location = useLocation()
  useEffect(() => {
    window.scrollTo(0, 0)
  }, [location])

  return <>{props.children}</>
}
Enter fullscreen mode Exit fullscreen mode

3 - Crie um arquivo chamado LandingPage.tsx em sua pasta src e adicione o seguinte:

// LandingPage.tsx
import { Link } from "react-router-dom"

const LandingPage = () => {
  return (
    <div style={{ margin: "auto", width: "80%" }}>
      <h1>Landing Page</h1>
      <div style={{ backgroundColor: "pink", height: 700 }}></div>
      <div style={{ backgroundColor: "orange", height: 700 }}></div>
      <div style={{ backgroundColor: "purple", height: 700 }}></div>
      <Link to="/product">
        <h2>Go To Product Page</h2>
      </Link>
    </div>
  )
}

export default LandingPage
Enter fullscreen mode Exit fullscreen mode

4 - Da mesma forma, crie um arquivo chamado ProductPage.tsx na pasta src e adicione o seguinte código:

// ProductPage.tsx
import { Link } from "react-router-dom"

const ProductPage = () => {
  return (
    <div style={{ margin: "auto", width: "80%" }}>
      <h1>Product Page</h1>
      <div style={{ backgroundColor: "green", height: 700 }}></div>
      <div style={{ backgroundColor: "grey", height: 700 }}></div>
      <div style={{ backgroundColor: "blueviolet", height: 700 }}></div>
      <Link to="/">
        <h2>Go To Home Page</h2>
      </Link>
    </div>
  )
}

export default ProductPage
Enter fullscreen mode Exit fullscreen mode

5 - Por último, mas não menos importante, remova todo o código padrão em App.tsx

Se você estiver usando o React Router v6+, adicione isto:

// App.tsx
import { BrowserRouter as Router, Routes, Route } from "react-router-dom"

import LandingPage from "./LandingPage"
import ProductPage from "./ProductPage"
import ScrollToTop from "./ScrollToTop"

const App = () => {
  return (
    <Router>
      <ScrollToTop>
        <Routes>
          <Route path="/" element={<LandingPage />} />
          <Route path="/product" element={<ProductPage />} />
        </Routes>
      </ScrollToTop>
    </Router>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Observe que o componente ScrollToTop envolve o componente Routes, mas permanece dentro do componente Router.

Se você estiver trabalhando com o React Router 5.x, use isto:

// App.tsx
import {
  BrowserRouter as Router,
  Route,
  Switch,
} from "react-router-dom"

import LandingPage from "./LandingPage"
import ProductPage from "./ProductPage"
import ScrollToTop from "./ScrollToTop"

const App = () => {
  return (
    <Router>
      <ScrollToTop>
        <Switch>
          <Route path="/" exact>
            <LandingPage />
          </Route>

          <Route path="/product">
            <ProductPage />
          </Route>
        </Switch>
      </ScrollToTop>
    </Router>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Observe que o componente ScrollToTop envolve o componente Switch, mas permanece dentro do componente Router.

Conclusão

Criamos um aplicativo simples de página única para demonstrar como rolar programaticamente até o topo da página em cada mudança de rota.


I hope you enjoyed the read!

Feel free to follow me on GitHub, LinkedIn and DEV for more!

Top comments (0)