Estudo sobre o Framework Remix
- 📝 My Notes - Acessar deploy ✅
- 💰 My Expenses - Acessar deploy ⏳
- ✅ Finalizado
- ⏳ Em andamento
- ✅ Componentes
- ✅ Hooks
- ✅ Funções
- 🎯 Principal
- 🔀 links
- 🌐 loader
- 🎬 action
- 📄 meta
- 🧤 CatchBoundary
- 🐛 ErrorBoundary
- ✅ Roteamento
Elementos do Remix para serem usados em formato de tags HTML / componentes React.
Componente especial que permite renderizar o conteúdo de uma rota filha dentro de um componente de layout pai.
Em outras palavras, um Outlet do Layout pai será substituído pelo conteúdo retornado pela Função Principal da rota filha.
import { Outlet } from "@remix-run/react";
export default function MeuLayout() {
return <Outlet />;
}
O componente ./app/root.jsx
(ou .tsx
) já possui um Outlet na criação do projeto Remix pois todas as rotas são filhas dele. O conteúdo carregado neste componente também será carregado em todas as Sub-Rotas do projeto.
O Outlet é uma peça fundamental do Remix para a criação de layouts e rotas flexíveis e reutilizáveis em aplicativos web, conteúdo que ficará mais claro nas outras seções desse documento.
Componente que permite aos usuários navegar entre diferentes rotas em um aplicativo web, sem precisar recarregar a página inteira. É semelhante à tag <a>
do HTML, mas é otimizado para uso com o framework Remix.
Ele deve ser usado somente para rotas da própria aplicação! Para rotas externas, use o
<a>
do HTML. E para ter mais segurança nesse caso, veja esta dica.
O endereço destino deve ser inserido como valor do atributo to
. Caso o valor inicie-se com barra (/
), o roteamento será feito a partir da raiz da aplicação. Mas caso o valor inicie-se sem a barra, o roteamento será feito de forma relativa, adicionando o endereço do link ao endereço atual separado por barra (ver Sub-rotas):
// Arquivo: routes/empresas/dados.tsx
import { Link } from "@remix-run/react";
export default function Dados() {
return (
<h1>Dados da empresa</h1>
<Link to="ends">Endereços</Link>
<Link to="/patrocinadores">Patrocinadores</Link>
);
}
No exemplo acima, o primeiro link será roteado para /empresas/dados/ends
e o segundo para /patrocinadores
.
Também é possível usar a notação ponto-ponto (
..
) como valor do atributoto
para indicar a super-rota (rota pai) da rota atual!
Funciona igual ao Componente Link, porém aplica uma classe CSS para o link ativo, ou seja, o link que leva à rota atual ficará destacado em relação aos links de outras rotas.
O funcionamento é bem simples. Basta, ao definir as folhas de estilo para os links, customizar o CSS para a pseudo-classe :active
e ela será aplicada automaticamente pelo Remix.
Funções especiais que fornecem acesso a recursos e funcionalidades específicas do framework.
Usado para navegar para uma rota específica do aplicativo. Ele retorna uma função que pode ser chamada para alterar a rota atual.
Permite acessar e manipular os parâmetros da URL da página. Ele retorna um objeto contendo os parâmetros da pesquisa da URL atual.
Usado para acessar dados pré-carregados em uma rota específica. Ele retorna um objeto contendo os dados de carregamento.
Usado para acessar dados relacionados a uma ação executada na rota atual. Ele retorna um objeto contendo os dados da ação.
Também conhecido como useNavigation, é usado para gerenciar transições entre páginas. Ele retorna uma função que pode ser chamada para iniciar uma transição para outra rota.
Usado para lidar com erros e exceções em uma rota específica. Ele permite definir uma função de callback para tratar os erros que ocorrem durante a execução dessa rota.
Trechos de código que devem seguir a nomenclatura proposta pelo Remix. Algumas funções são escritas em camelCase e outras em PascalCase.
O nome Principal
será usado como exemplo de um nome de um componente:
export default function Principal() {
return <p>Hello, World!</p>;
}
Essa função é executada sempre que uma requisição do tipo GET é requisitada para a rota. Seu conteúdo de retorno será renderizado na tela.
Função que retorna itens para serem adicionados na tag links do HTML gerado:
<html>
<head>
<!-- Exemplo 1: -->
<link />
<!-- Exemplo 2: -->
<link />
</head>
</html>
Muito usado para adicionar estilos via arquivo.css quando não usa-se framework CSS que dispensa arquivo segregado para estilos, como Tailwind e Bootstrap.
Função executada sempre que uma requisição do tipo GET
é executada na rota. Usada para carregar dados que serão usados na renderização.
Seu retorno é acessado na Função Principal do componente usando o hook useLoaderData()
. Nesse caso, a Função CatchBoundary pode ser usada para capturar erros e lidar com exceções durante a busca de dados.
Função executada sempre que uma requisição diferente de GET
é executada na rota. Pode ser usada para buscar dados necessários em resposta a uma ação do usuário, como enviar um formulário.
O código dessa função é executado do lado do servidor e seu código fonte não é sequer enviado para o cliente. Nesse caso, a Função CatchBoundary pode ser usada para capturar erros e lidar com exceções durante a busca de dados.
Função usada para adicionar metadados nas páginas da aplicação. Ela deve retornar um objeto do JavaScript com os membros desejados:
export function meta({ data }) {
return {
title: data.tituloDaPagina,
description: data.descDaPagina,
};
}
O metadado de cada página é mesclado, e sobrescrito, quando se aplica, com o conteúdo da super-rota (rota pai).
Note que ela pode receber um parâmetro que será enviado automaticamente em sua chamada pelo Remix. Ela é executada depois da Função loader, então todos os dados necessários para ela já foram carregados.
Função que representa o componente que será renderizado no lugar da Função Principal quando houver um erro do tipo JavaScript Response em qualquer lugar da aplicação. É usada para capturar erros relacionados à renderização, mas não se limita a isso. Ela pode capturar erros que ocorrem durante a execução da Função loader ou durante a renderização do componente, independentemente do motivo do erro:
// Usando Response, suportada pelo Node.js e navegadores:
throw new Response();
// Usando a função de response do remix importada de "@remix-run/node":
throw json();
Pode ser usada no root.tsx do projeto ou em um componente de rota. Se for usada no root, substituirá toda a página. Se for usada em um componente, substituirá somente o conteúdo retornado por esse componente mas manterá o trecho presente no root, com exceção do conteúdo do Componente <Outlet />.
Função que representa o componente que será renderizado no lugar da Função Principal quando um erro tipo Error do JavaScript for lançado. É usada especificamente para capturar erros em componentes filhos e exibi-los de forma amigável para o usuário final:
// Lançando erro sem construir um objeto:
throw "Errôneo";
// Lançando erro construindo um objeto simples:
throw Error("E-Romeu");
// Lançando erro construindo um objeto complexo:
throw new Error("Herrar é umano");
Pode ser usada no root.tsx do projeto ou em um componente de rota. Se for usada no root, substituirá toda a página. Se for usada em um componente, substituirá somente o conteúdo retornado por esse componente mas manterá o trecho presente no root, com exceção do conteúdo do Componente <Outlet />.
Caminhos que definem como a aplicação web responderá às solicitações dos usuários.
A hierarquia de sub-rotas pode ser definida de duas maneiras:
-
Usando diretórios:
routes ├── auth │ ├── login.tsx │ └── logout.tsx └── dashboard ├── aulas │ └── $idAula.tsx └── notas.tsx
-
Usando o símbolo de ponto final (
.
):routes ├── auth.login.tsx ├── auth.logout.tsx ├── dashboard.aulas.$idAula.tsx └── dashboard.notas.tsx
O ponto que separa a extensão do arquivo não é convertido em sub-rota.
Ambos as maneiras acima geram as páginas:
/auth/login
/auth/logout
/dashboard/aulas/<id-aula>
/dashboard/notas
As rotas dinâmicas podem ser criadas usando o símbolo $
ao nomear um arquivo. A palavra que segue o símbolo, será usada como placeholder no nome da rota.
/* Arquivo ~/routes/animais.$nomeDoAnimal.tsx */
// Importações omitidas
export default function PaginaDetalhesDoAnimal() {
const animal = useLoaderData();
return (
<main>
<header>
<h1>{animal.nome}</h1>
</header>
<p>{animal.detalhes}</p>
</main>
);
}
export async function loader({ params }: ActionArgs) {
const nomeDoAnimal = params.nomeDoAnimal;
const animal = await obterAnimalPorNome(nomeDoAnimal);
return animal;
}
Note que o nome do arquivo é animais.$nomeDoAnimal.tsx
, ou seja, a rota para esta página será /animais/cachorro
ou /animais/coelho
, como visto nas Sub-Rotas.
Layouts são componentes React que envolvem rotas para fornecer uma estrutura comum para elas, permitindo definir elementos de interface do usuário que são comuns a todas as páginas. Isso significa que um layout é um componente renderizado para um conjunto de sub-rotas pré definido:
routes
├── fornecedores.tsx
├── clientes.tsx <- Layout
└── clientes <- Contém sub-rotas que usarão o layout
├── cadastro.tsx
└── arquivos.tsx
No exemplo acima, todas as páginas dentro do diretório clientes
serão renderizadas dentro do layout clientes.tsx
. Basta fazer uso do Componente Outlet no arquivo de layout:
import { Outlet } from "@remix-run/react";
export default function ClientesLayout() {
return (
<main>
<h1>Conteúdo renderizado em todas as sub-rotas de /clientes/"</h1>
<Outlet />
</main>
);
}
Esse mesmo conceito é aplicado nos arquivos ./app/root.tsx
de cada projeto Remix.
Para fazer com que uma sub-rota não utilize o layout que está sendo aplicado em seu conjunto, basta remover o arquivo correspondente da pasta pai e usar a notação de ponto para determinar a hierarquia de rotas, como visto em Sub-Rotas:
routes ├── fornecedores.tsx ├── clientes.tsx <- Layout ├── clientes.arquivos.tsx <- Sub-rota que não usará o layout └── clientes <- Contém sub-rotas que usarão o layout └── cadastro.tsx
Técnica de roteamento utilizada para criar rotas de página que não têm um caminho explícito definido.
Ao utilizar uma rota de layout sem caminho (pathless), o componente de layout é renderizado em todas as rotas filhas, independentemente de seu caminho específico.
Isso permite compartilhar um mesmo layout entre várias rotas ou grupos de rotas, sem repetição de código ou necessidade de definir caminhos separados para cada uma delas.
Para criar um Layout assim, criamos um diretório e um arquivo React com o nome contendo o prefixo duplo underscore (__
), como mostrado no exemplo:
routes
└── cadastros
├── __clientes.tsx <- Layout sem caminho
└── __clientes <- Contém rotas com o Layout
├── ativos.tsx
└── inativos.tsx
// Arquivo: routes/cadastros/__clientes.tsx
import { Outlet } from "@remix-run/react";
import dummyStyles from "~/styles/dummy.css";
export default function ClientesLayout() {
return <Outlet />;
}
export function links() {
return [{ rel: "stylesheet", href: dummyStyles }];
}
No caso acima, um Layout sem caminho foi usado para compartilhar folhas de estilo entre duas rotas sem alterá-las:
- /cadastros/ativos
- /cadastros/inativos
São rotas que não geram uma página, por isso não possuem uma Função Principal, mas sim uma Função loader.
Por exemplo: é possível retornar um objeto da função:
export function loader() {
return {
nome: "Helton",
sobrenome: "Santos",
frontend: "Remix.run",
};
}
Também conhecidas como Splat Routes, compõem uma técnica de roteamento que permite definir rotas com curingas (wildcards) para capturar um conjunto variável de parâmetros em uma URL.
Para definir uma rota de splat no Remix, você pode utilizar o caractere asterisco (*
) na definição do caminho da rota. Por exemplo, uma rota com o caminho /users/*
irá corresponder a qualquer URL que comece com /users/
, seguida por qualquer sequência de caracteres.
Quando o usuário acessa uma URL que corresponde a uma rota de splat, o valor correspondente ao curinga é capturado e disponibilizado para ser utilizado na Função loader da rota. Dessa forma, você pode utilizar esses parâmetros para carregar dados específicos de acordo com a URL acessada pelo usuário.
O arquivo contendo a rota curinga deve ser nomeado como cifrão.extensão
: $.jsx
ou $.tsx
:
import { redirect } from "@remix-run/node";
export function loader({ params }) {
if (params["*"] === "encurta-link/clientes") {
return redirect("/cadastros/pessoas/clientes/lista-de-clientes-ativos");
}
return new Response("Página não encontrada", { status: 404 });
}
No exemplo acima, o usuário que acessar:
www.meu-app.com/encurta-link/clientes
será redirecionado para:
www.meu-app.com/cadastros/pessoas/clientes/lista-de-clientes-ativos
O Remix permite que existam vários arquivos de rota curinga no projeto. Nesse caso, a rota curinga acionada será sempre a de ascendente mais próxima.