React: Componente Select com Typescript, react-select e styled-components
Olá!
Quero ir direto ao ponto neste artigo. Nos últimos dias, precisei criar um componente select e, por conveniência, escolhi duas bibliotecas que já utilizei/utilizo no meu dia-a-dia.
O intuito desta publicação é facilitar a utilização de typescript junto da biblioteca react-select. Pois, tive alguns problemas para “tipar” as propriedades do meu componente select customizado.
Direto ao código
O componente do styled-components
Primeiramente, temos nosso componente de estilização do styled-component:
export const StyledSelect = styled(Select)`` as typeof Select;
Nenhum segredo aqui, apenas que você deve utilizar type assertion: as typeof Select
.
Para entender melhor o motivo, confira a issue criada no github.
Nosso componente customizado
function CustomSelect<
Option,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>
>(props: Props<Option, IsMulti, Group>) {
return <StyledSelect {...props} />;
}
Basicamente criamos um componente Wrapper para nosso componente de estilo do styled-components
. Como estamos utilizando tipos de uma biblioteca externa, esse código não é chute, a própria documentação do react-select
nos ensina a criar um Wrapper.
Utilizando forwardRef
Pode ser que você precise utilizar seu novo componente select junto de bibliotecas que utilizem ref/ou você mesmo precisará criar um comportamento associado aos controles nativos que o ref te oferece.
Para isso, você terá que atualizar seu código da seguinte forma:
Há um ponto importante nesse código, não há maneiras diretas de utilizar tipos genéricos no componente de retorno do forwardRef. Por isso, eu utilizei type assertion (Para mim, a forma mais concisa de contornar este problema).
Para entender um pouco mais sobre este comportamento e outras formas de resolver, recomendo que leia esta publicação no Stackoverflow:
Agradecimentos
Gostaria de agradecer pela sua atenção. Caso esta publicação tenha te ajudado, não deixe de compartilhar com seus colegas.