DEV Community

<deMGoncalves />
<deMGoncalves />

Posted on • Updated on

Implementando um sistema de slots em React para componentes reutilizáveis

Dev coautor @mandado

Um dos princípios fundamentais do desenvolvimento de software é a reutilização de código. Ao criar componentes em React, desejamos construí-los de forma modular e flexível, para que possam ser facilmente adaptados e reutilizados em diferentes contextos. Neste artigo, exploraremos a implementação de um sistema de slots em React, que permite a composição de componentes de forma dinâmica e personalizada.

Entendendo o conceito de slots

Slots são espaços reservados dentro de um componente, nos quais outros componentes ou elementos podem ser inseridos. Eles fornecem um mecanismo flexível para a composição de interfaces, permitindo que partes específicas de um componente sejam personalizadas ou substituídas sem alterar a estrutura geral do componente.

Implementando o sistema de slots

Vamos começar implementando o componente Slot, que será responsável por renderizar os elementos filhos em slots específicos. Veja o código abaixo:

import { Children, Fragment, ReactNode, isValidElement } from 'react';

type SlotProps = {
  children: ReactNode;
  name: string;
};

export const Slot = ({ name, children }: SlotProps) => {
  const elements = Children.toArray(children).filter(child => {
    if (isValidElement(child)) {
      return child.type.toString().includes(`slot: "${name}"`) || child?.props?.slot === name;
    }

    return false;
  });

  return <Fragment>{elements}</Fragment>;
};

Enter fullscreen mode Exit fullscreen mode

Neste código, importamos as dependências necessárias do React e, em seguida, definimos o componente Slot. Ele recebe duas propriedades: name, que representa o nome do slot, e children, que são os elementos a serem renderizados dentro do slot.

Dentro do componente Slot, utilizamos a função Children.toArray para garantir que os elementos filhos sejam tratados como uma matriz. Em seguida, filtramos esses elementos com base na propriedade slot de cada um. Aqueles que correspondem ao nome do slot são mantidos na matriz elements.

Por fim, retornamos os elementos filtrados encapsulados em um Fragment, que é usado para evitar a criação de um nó HTML adicional desnecessário.

Utilizando o sistema de slots em um componente

Agora que temos o componente Slot implementado, podemos usá-lo para criar componentes reutilizáveis e flexíveis. Vamos criar um exemplo de componente chamado TopAppBar, que possui três slots: leading, headline e trailing. Veja o código abaixo:

import Slot from './slot';
import React, { ReactNode } from 'react';

type TopAppBarProps = {
  children: ReactNode;
};

const TopAppBar = ({ children }: TopAppBarProps) => (
  <header>
    <div>
      <Slot name='leading'>{children}</Slot>
    </div>
    <div>
      <Slot name='headline'>{children}</Slot>
    </div>
    <div>
      <Slot name='trailing'>{children}</Slot>
    </div>
  </header>
);

export default TopAppBar;
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, importamos o componente Slot e o utilizamos dentro de TopAppBar. Cada Slot é definido em um elemento div, com um nome específico passado como propriedade. O conteúdo personalizado para cada slot é definido dentro das tags de abertura e fechamento do componente TopAppBar.

Compondo componentes usando slots

Agora que temos nosso componente TopAppBar com slots definidos, podemos utilizá-lo em nosso aplicativo e personalizá-lo de acordo com nossas necessidades. Veja o exemplo abaixo:

import TopAppBar from './topappbar';

const App = () => (
  <TopAppBar>
    <h1 slot='headline'>Hello World</h1>
  </TopAppBar>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

Neste exemplo, importamos o componente TopAppBar e o utilizamos no componente App. Dentro do TopAppBar, especificamos que o componente <h1> deve ser renderizado no slot headline usando a propriedade slot.

Conclusão

Neste artigo, exploramos a implementação de um sistema de slots em React, permitindo a criação de componentes reutilizáveis e flexíveis. Através do componente Slot, conseguimos definir espaços reservados dentro de um componente onde outros componentes ou elementos podem ser inseridos de forma personalizada.

Com o uso de slots, é possível compor interfaces dinamicamente e adaptá-las de acordo com diferentes contextos. Essa abordagem oferece uma maneira poderosa de criar componentes modulares e extensíveis, promovendo a reutilização de código e facilitando a manutenção do projeto.

Espero que este artigo tenha sido útil para entender e implementar o sistema de slots em React. Ao adotar essa abordagem em seus projetos, você estará criando componentes mais flexíveis e adaptáveis, o que contribui para uma melhor experiência de desenvolvimento e uma arquitetura mais modular.

Obrigado por ler e boa sorte em suas implementações com slots no React!

Agradecimento

Gostaria de expressar meu sincero agradecimento ao @mandado por sua valiosa ajuda na implementação do componente Slot. Sua colaboração foi fundamental e estou muito grato por todo o suporte fornecido.

Obrigado pelo seu tempo e contribuição!

Top comments (1)

Collapse
 
mandado profile image
Jorge Roberto Tomaz Junior

Eu que agradeço demais pelas trocas de conhecimento!