Como eu quero que esse texto seja uma leitura rápida não vou colocar nenhuma implementação do código
Vamos começar imaginando que o time de design lhe entregou o Menu abaixo no figma e agora chegou a sua hora de implementa-lo
Uma implementação válida poderia ser:
<Menu
trigger={<MoreIcon />}
config={{
onClick: someFunction,
label: "Delete"
}}
/>
Parabéns! Você conseguiu entregar o menu e já pode pegar outras tarefas.
Passou algum tempo e agora aquele menu que você fez precisa ser mais flexível e capaz de receber mais features, como por exemplo, mais um botão para poder editar algo.
Vendo o novo design, você decide atualizar o objeto de configuração, para algo semelhante com o código abaixo:
<Menu
trigger={<MoreIcon />}
config={[
{
label: 'Edit',
onClick: someFunction1,
},
{
label: 'Delete',
onClick: someFunction2,
}
]}
/>
uhuuuul! Esse menu não é mais probl… POW, surge do nada, sem nenhum aviso um novo menu…
Agora você começa a ficar chateado por estar preso nesse menu durante um bom tempo e, mais uma vez, você precisa voltar nele e alterá-lo.
<Menu trigger={<MoreIcon />} config={[
{
title: "\"safe actions\","
items: [
{
label: 'Edit',
onClick: someFunction1,
align: 'left',
}
],
hasDividerBellow: true,
},
{
title: "\"unsafe actions\","
items: [
{
label: 'Edit',
onClick: someFunction2,
align: 'left',
color: 'red',
}
],
hasDividerBellow: false,
},
]} />
Você decide seguir a implementação com o objeto de configuração a cima e pronto! Acabamos com a nossa historinha e já podemos analisar alguns fatores sobre ela.
Se em algum momento você chegou nesse ponto, provavelmente pensou algumas coisas, como:
- Esse código tá uma bagunça!!!
- Se eu soubesse que o componente final seria, teria feito um código muito melhor!
- Esse código tá muito complexo, acho que vou fazer um refactor depois (SPOILER: O depois nunca chegou)
ISSO É NORMAL, principalmente se você for iniciante. Então, vamos seguir adiante e analisar quais os maiores problemas da abordagem a cima:
- Toda feature nova vai precisar de um novo refactor
- Conforme a quantidade de features do seu objeto aumentar, mais difícil vai ser manter o componente devido ao aumento da complexidade, ou seja não é muito escalável
- A legibilidade do seu código vai diminuindo cada vez mais.
OK, o que podemos fazer para evitar isso? existe uma solução? SIM!
Compound Components no lugar de objetos de configuração
A ideia por trás dos compound components baseia-se na mudança da quantidade de componentes: anteriormente, você possuía apenas um componente com um objeto de configuração; e agora, você tem dois ou mais componentes que trabalham juntos para realizar algo. Ou seja, você vai separar a sua solução única em mais de um componente para que depois eles possam compor a solução final. (daí o nome 🤯)
Vamos ver então como ficaria as implementações acima utilizando o padrão do compound components.
Para o primeiro caso:
<Menu trigger={<MoreIcon />}>
<Menu.Container>
<Menu.Button label="Delete" onClick={someFunction1} />
</Menu.Container>
</Menu>
Enquanto o segundo ficaria parecido com:
<Menu trigger={<MoreIcon />}>
<Menu.Container>
<Menu.Button label="Edit" onClick={someFunction1} />
<Menu.Button label="Delete" onClick={someFunction1}
</Menu.Container>
</Menu>
E o último ficaria:
<Menu trigger={<MoreIcon />}>
<Menu.Container>
<Menu.Section title="safe actions">
<Menu.Button label="Edit" onClick={someFunction1} />
</Menu.Section>
<Menu.Divider />
<Menu.Section title="unsafe actions">
<Menu.Button label="Delete" onClick={someFunction1}
</Menu.Section>
</Menu.Container>
</Menu>
Concluindo
A grande vantagem de seguir esse padrão esta na sua flexibilidade. No caso acima, por exemplo, você não precisaria ficar voltando no componente e refatorando o código toda vez que o menu precisasse de uma feature nova, você iria apenas criar novos componentes.
Outra vantagem está na legibilidade, já que cada componente tende a ser pequeno e/ou ter uma responsabilidade bem específica, facilitando a manutenção dos mesmos.
Top comments (0)