E aí, programador! o/

Nessa aula você irá começar a criar sua primeira SPA usando React e React Router.

  1. Crie um novo projeto React com o Vite. Instale as dependências e remova o conteúdo desnecessário do componente App.jsx.

  2. Instale o React Router:

    npm install react-router-dom
    
  3. Antes de pasarmos para o uso do React Router, vamos criar alguns componentes. Crie um arquivo JSON com dados de exemplo. Crie também a pasta “components” e, dentro dela, crie os componentes a seguir:

  4. Agora que temos componentes para exibir vamos criar as rotas, ou telas, do app. Para isso, crie na pasta “src” um arquivo chamado “router.jsx”:

    Obs.: existem outros sistemas de rotas, mas o mais comum é o BrowserRouter, que é o sistema padrão do navegador, que usa o histórico de páginas.

    import { createBrowserRouter } from "react-router-dom"
    import Admin from "./components/Admin";
    import Home from "./components/Home";
    import Products from "./components/Products";
    import Cart from "./components/Cart";
    
    const router = createBrowserRouter([
      {
        path: "/",
        element: <Home />,
      },
    	{
        path: "/products",
        element: <Products />,
      },
    	{
        path: "/cart",
        element: <Cart />,
      },
      {
        path: "/admin",
        element: <Admin />,
      }
    ])
    
    export default router;
    
  5. Com o roteador pronto, atualize o componente princpal App.jsx para incluir o roteador através do RouterProvider:

    import { RouterProvider } from "react-router-dom"
    import router from "./router"
    
    function App() {
      return (
        <RouterProvider router={router} />
      )
    }
    
    export default App
    
  6. Temos as rotas funcionando, mas um ponto importante das SPAs é a navegação transparente, ou seja, de forma imperceptível e sem atualizar a página. Para isso, o React Router oferece um componente especial que substitui o elemento <a> padrão, o componente Link. Crie uma barra de navegação no app usando alguns links:

    import { Link } from "react-router-dom";
    
    export default function Products() {
      return (
        <section>
    			<header>
            <nav style={{ display: "flex", gap: "2rem" }}>
              <Link to="/products">Produtos</Link>
              <Link to="/cart">Carrinho</Link>
            </nav>
          </header>
          <h2>Todos os produtos</h2>
    
    // ...
    
    import { Link } from "react-router-dom";
    
    export default function Cart() {
      return (
        <section>
    			<header>
            <nav style={{ display: "flex", gap: "2rem" }}>
              <Link to="/products">Produtos</Link>
              <Link to="/cart">Carrinho</Link>
            </nav>
          </header>
          <h2>Carrinho</h2>
          <p>Os produtos atualmente em seu carrinho.</p>
    
    // ..
    
  7. A SPA já está funcional. Agora, para deixá-la ainda melhor, podemos fazer mais alguns ajustes. Primeiro, em uma SPA como essa é bom que separemos os componentes menores dos componentes de telas/páginas. Para isso, crie uma nova estrutura dentro de uma pasta “pages” como mostra a figura:

    Obs.: você pode usar o nome que quiser, algumas escolhas comuns são: “pages”, “views”, “screens” ou “routes”.

    Untitled

  8. Outra coisa que podemos fazer para evitar repetições é usar um layout base. O React Router permite adicionar filhos a uma rota, e todo herdam o conteúdo do componente pai. Isso é muito útil para estruturas comuns entre várias páginas, como navegação, barras laterais, rodapé, etc.

  9. Remova os cabeçalhos de navegação em Products.jsx e Cart.jsx e crie um componente pai chamado Layout.jsx na pasta “pages”:

    Obs.: repare que podemos escolher exatamente onde queremos que os filhos apareçam na tela através do componente especial <Outlet /> do React Router.

    import { Link, Outlet } from "react-router-dom";
    
    export default function RootLayout() {
      return (
        <>
          <header>
            <nav style={{ display: "flex", gap: "2rem" }}>
              <Link to="/">Início</Link>
              <Link to="/products">Produtos</Link>
              <Link to="/cart">Carrinho</Link>
              <Link to="/admin">Administração</Link>
            </nav>
          </header>
          <main>
            <p>Esse é o layout principal. Abaixo está o conteúdo dinâmico de cada rota filha.</p>
            <hr />
            <Outlet />
          </main>
          <footer>
            <p>Feito com React Router DOM =D</p>
          </footer>
        </>
      )
    }
    
  10. Agora só precisamos ajustar o roteador para trabalhar com a nova estrutura. Adicione a rota base “/” e coloque as rotas “/products” e “/cart” como filhas dela:

    Obs.: repare que a rota “/admin” continua funcionando separadamente e, portanto, não herda o layout base.

    import { createBrowserRouter } from "react-router-dom"
    import RootLayout from "./pages/Layout";
    import AdminHome from "./pages/admin/Home";
    import Home from "./pages/Home";
    import Products from "./pages/Products";
    import Cart from "./pages/Cart";
    
    const router = createBrowserRouter([
      {
        path: "/",
        element: <RootLayout />,
        children: [{
          index: true,
          element: <Home />
        }, {
          path: "products",
          element: <Products />
        }, {
          path: "cart",
          element: <Cart />
        }]
      },
      {
        path: "/admin",
        element: <AdminHome />
      }
    ])
    
    export default router;