DEV Community

Cover image for Criando um Layout Persistente em NextJS
Guilherme Selair
Guilherme Selair

Posted on

Criando um Layout Persistente em NextJS

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.

Alt Text

# 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} />
  );
}
Enter fullscreen mode Exit fullscreen mode

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} />
    </> 
  );
}
Enter fullscreen mode Exit fullscreen mode

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:

Alt Text

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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>
    </> 
  );
}
Enter fullscreen mode Exit fullscreen mode

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!

# Referências

Top comments (3)

Collapse
 
lucaspedroabreu profile image
Lucas Pedro Abreu

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.

Collapse
 
jrmarqueshd profile image
Junior Marques

Parabéns pelo post, amigo! Achei bem legal a dinâmica que usou para explicar sobre os componentes.

Collapse
 
renatomoratto profile image
Renato Willyan Moratto Filho

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!