Como da pra notar pelo outros posts, sempre que tenho que implementar algo novo para mim, eu tento postar aqui para ajudar o máximo de pessoas possível e hoje não é diferente!
Então pega um ☕ e curte o post.
# Introdução
Podemos dizer que temos um layout persistente quando um componente é compartilhado em diversas telas de nossa aplicação sem sofrer re-renderizações pela troca de páginas. De maneira mais clara é quando declaramos apenas uma vez o componente para ser utilizado em parte ou em toda a aplicação. Um exemplo disso é o cabeçalho e o rodapé de um projeto que são normalmente compartilhados em diversas páginas porém declarados um vez.
# Explicando o exemplo 🤯
No exemplo que vamos construir aqui, quero além de exibir o cabeçalho em todas as páginas, quero também só que apenas nas páginas que estão dentro da pasta /pages/minha-conta/*
exibam um menu de navegação lateral.
Abaixo há uma imagem para explicar melhor o que será desenvolvido.
# Ao código! 👨💻
## Adicionando cabeçalho e entendendo o uso de App
Como estamos usando o nextjs para este exemplo, nosso arquivo _app.js
deve ser parecido com esse:
export default function App({ Component, pageProps }) {
return (
<Component {...pageProps} />
);
}
Como você deve saber, toda página que temos em nossa aplicação na hora de sua execução ela será executada como o Component
acima.
Por exemplo: temos a página meus-dados.js
quando o usuário acessar esta página em seu navegador, o nextjs "enviará" o componente exportado pela página de meus-dados.js
para o arquivo _app.js
. Neste arquivo obtemos o componente a ser executado e suas propriedades (caso tenha), e em seguida o executamos utilizando <Component />
.
Entendido isso então percebemos que conseguimos envolver este Component
com um Fragment Operator para possibilitar a renderização de qualquer outro componente junto com a página em execução.
Portanto conseguimos adicionar um componente que será exibido em todas as páginas de nossa aplicação dessa maneira:
export default function App({ Component, pageProps}) {
return (
<>
<Header />
<Component {...pageProps} />
</>
);
}
Show! Cabeçalho adicionado ✅ 👏
## Adicionando menu lateral
Para adicionar o menu lateral somente para as páginas que fazem parte da pasta minha-conta
precisamos realizar mais algumas alterações.
A ideia que eu quero aqui é: Declarar apenas uma vez o componente do menu lateral e fazer ele parecer em todas as páginas da pasta
minha-conta
.
Usarei aqui como exemplo as páginas /pages/minha-conta/meus-dados
e /pages/minha-conta/alterar-senha
.
Abaixo fica mais claro o nosso objetivo:
Precisamos de um filtro para selecionar em qual tela devemos exibir o menu. Não podemos apenas adicionar o componente junto ao cabeçalho como fizemos acima pois senão o menu seria renderizado em todas as telas.
Vamos então construir um novo componente que envolverá todas as páginas que precisamos e nele adicionarmos o componente de menu. Vou chamar de MyAccountLayout esse componente que criaremos.
import SideMenu from '../_components/SideMenu';
const MyAccountLayout = ({ children }) => (
<>
<SideMenu />
{ children }
</>
);
export default MyAccountLayout;
Como o componente acima servirá como um wrapper precisamos que ele aceite os children
que são todos os componentes envolvidos por ele.
Agora em todas as páginas que o menu deve aparecer, devemos adicionar uma propriedade no componente a ser exportado. O nome dessa propriedade pode ser qualquer um, eu vou chamar de layout. É nessa propriedade layout
que vamos adicionar o componente MyAccountLayout
que criamos acima.
//Página de meus-dados
import MyAccountLayout from '../_layout';
const UserData = () => (
{...}
);
UserData.layout = MyAccountLayout;
export default UserData;
Para finalizar, no arquivo _app.js vamos criar um componente para receber o conteúdo da propriedade layout
caso exista, caso não exista vamos adicionar um Fragment Operator. Além disso vamos envolver o Component
pelo componente criado.
export default function App({ Component, pageProps}) {
const CustomLayout = Component.layout ? Component.layout : React.Fragment;
return (
<>
<Header />
<CustomLayout>
<Component {...pageProps} />
</CustomLayout>
</>
);
}
Com isso já temos o que queríamos! Menu lateral adicionado apenas nas páginas da pasta minha-conta
.
E o melhor, você consegue fazer qualquer outro layout persistente usando esta mesma técnica, basta criar o componente de seu layout e atribui-lo a propriedade layout
do componente da página. Show né!
# Conclusão 😻
Chegamos ao fim de mais um post e então, gostou?
Sempre busco explicar o máximo que consigo para que todos que leiam entendam o que estamos fazendo e consigam aplicar em seus projetos.
Sobre a maneira que fizemos o layout persistente, vale salientar que existem inúmeras maneiras de fazer isso, este foi o jeito que mais gostei seguinte as dicas do link nas referências.
See you soon!
Top comments (3)
Opaa, como é bom ver uma boa explicação dessas em português!!
Infelizmente, passaram-se dois anos do outro artigo de refêrencia (do criador do tailwind css) e o next.js parece ainda não implementado alguma função parecida como o que realiza esse tipo de tarefa e está sendo muito anunciada no remix.js e que existem em outros frameworks como Vue e Angular.
Vale lembrar que no artigo dele ele sugere usar uma função na propriedade do layout, que fica um pouco mais complexo, mas para evitar re-renderizações quando a navegação se dá no componente superior.
Parabéns pelo post, amigo! Achei bem legal a dinâmica que usou para explicar sobre os componentes.
Pode parecer algo besta, mas estou há dois dias tentando fazer um layout que apareça somente após o login ser efetuado e seu post foi o que me ajudou a conseguir. Parabéns pela explicação!