Reaja os Ganchos Personalizados e a morte de Render Props

Todos tinham algo a dizer sobre o React Hooks quando foi apresentado no mês passado. Mas eu não vi ninguém dizer que podemos parar de usar o Render Props. Então eu vou dizer isso. Nós podemos parar de usar o Render Props. Neste artigo, aprenderemos a fazer exatamente isso.

Aditya Agarwal Blocked Desbloquear Seguir Seguindo 3 de dezembro de 2018

Nota – Render Props não vai morrer completamente , mas eles não serão usados para o que estamos acostumados. Além disso, React Hooks ainda estão em alfa, portanto, não é recomendado usá-los na produção . Por favor, não se apresse em refatorar todos os seus aplicativos existentes.

O que são renderizações?

Render Props é um padrão avançado para compartilhar lógica entre componentes. Um componente (normalmente denominado Componente do Contêiner) pode delegar como a interface do usuário se parece com outros componentes (chamados componentes de apresentação) e somente implementar a lógica de negócios em si. Assim, podemos implementar interesses transversais como componentes usando o padrão Render Props.

Por que precisamos de Render Props?

  1. Para compartilhar código entre componentes
  2. Para usar a API de contexto

O problema com Render Props

Usando Render Props vem com seus próprios problemas. Alguns desses problemas aparecem apenas quando nos aprofundamos ou quando dimensionamos nosso projeto.

Inferno do invólucro

Para aumentar a DRYness de nossa base de código, muitas vezes implementamos muitos componentes pequenos e granulares, de modo que cada componente lida com apenas uma preocupação. O problema com isso é que muitas vezes ficamos com um monte de componentes wrapper aninhados profundamente dentro de um outro. Se diminuirmos o número de componentes do wrapper, o tamanho e a complexidade do componente aumentam. Além disso, a capacidade de reutilização de um componente wrapper também pode diminuir. Este tweet resume perfeitamente.

Vincular "isso" é uma dor

Como os componentes do wrapper lidam com métodos de estado ou de ciclo de vida, eles precisam usar os componentes de classe. Com Componentes Classe temos que ligar this corretamente caso contrário corremos o risco de perder a this contexto dentro de funções. A sintaxe para vincular todos os métodos parece feia e é um fardo para os desenvolvedores.

As aulas são difíceis para humanos e máquinas

Classes vêm com uma boa quantidade de código clichê que é horrível para nós escrevermos toda vez que convertemos um componente funcional em um componente de classe. Acontece que as classes são difíceis de otimizar pelas nossas ferramentas de construção também. Isso incorre em uma penalidade dupla, porque não leva a um bom DX (experiência do desenvolvedor), nem à boa experiência do usuário (UX). A equipe do React está até pensando em mover o suporte a componentes de classe para um pacote separado no futuro.

O uso do PureComponent se torna complicado

Usar um suporte de renderização pode negar a vantagem que resulta do uso do PureComponent se criarmos a função atribuída dentro do método de renderização. Isso ocorre porque a comparação superficial prop sempre retornará false para novos objetos , e cada render, nesse caso, gerará um novo valor para o objeto prop. Consulte os documentos para mais detalhes.

Muitos desses problemas não são totalmente culpa do padrão Render Props. Até agora, o React não fornecia uma maneira de usar métodos de estado ou de ciclo de vida sem envolver classes e é por isso que precisávamos usar classes em componentes de contêiner para implementar o padrão Render Props.

No entanto, tudo isso muda com a introdução da API React Hooks. React Hooks nos permite usar ganchos de estado e ciclo de vida dentro de componentes funcionais com apenas algumas linhas de códigos.

O que é ainda melhor é que podemos implementar nossos próprios ganchos personalizados. Esses ganchos nos dão uma nova, fácil e poderosa primitiva para compartilhar a lógica entre os componentes. Isso significa que não precisamos de classes ou renderizar props padrão para compartilhar código entre componentes. Antes de entrar nisso, vamos primeiro dar uma boa olhada em como o React Hooks pode ser usado.

Um exemplo básico de Ganchos de Reação

A melhor maneira de aprender alguma coisa é usando-a. Então, para usar o React Hooks, criaremos um componente que, por padrão, mostra algumas informações e nos permite atualizar essas informações clicando em um botão. Vai parecer algo assim.

Item editável com ganchos de reação (clique aqui para vídeo)

O que podemos observar é que o componente possui dois tipos de estados. Um estado é para controlar o campo de entrada e o outro estado é para alternar entre o visualizador e o editor. Vamos ver como isso pode ser implementado com React Hooks.

Link para o código

Nós definimos um componente funcional chamado EditableItem, que recebe dois props, label e initialValue. label prop é para mostrar o rótulo acima do campo de entrada e o initialValue prop é para mostrar as informações padrão.

Chamar o gancho useState nos fornece uma matriz de dois itens, o primeiro é para leitura de estado e o próximo é para atualizar esse estado. Manteremos o estado da entrada controlada na variável de valor e a função de atualizador de estado na variável setValue . Por padrão, a variável de valor será atribuída aos dados prop de initialValue .

Em seguida, mantemos o estado para alternar entre visualizador e editor na variável editorVisible e seu atualizador na variável setEditorVisible . Na marcação, renderizamos o visualizador quando o valor de editorVisible é falso e renderizamos o editor quando o valor é true. Como queremos mostrar o visualizador por padrão, precisamos ter o valor editorVisible como falso inicialmente. É por isso que passamos falso ao chamar o useState .

Para alternar entre o visualizador e o editor, definimos uma função toggleEditor que define o estado editorVisible como oposto toda vez que a função é chamada. Como queremos chamar esta função sempre que o usuário clica no botão, nós o atribuímos como onClick prop do botão.

É fácil usar o React Hooks, mas ele não para por aqui. Os ganchos têm mais um truque em suas mangas e isso é Ganchos Personalizados. Podemos ver que o estado editorVisible é na verdade um toggler e toggling é um caso de uso muito comum em nossas interfaces. Se quiséssemos compartilhar a lógica de alternância entre componentes, definiríamos um componente Toggler e usaríamos o padrão render props para compartilhar o método toggling. Mas não seria mais fácil se pudéssemos ter uma função para isso em vez de mexer nos componentes? Insira ganchos personalizados…

Usando ganchos de reação personalizados para compartilhar lógica entre componentes

Com Ganchos Personalizados, podemos extrair a lógica de alternância do componente EditableItem para uma função separada. Vamos chamar esta função useToggle como recomenda-se iniciar o nome de um gancho personalizado com a palavra “use”. O gancho personalizado useToggle ficará assim:

Link para o código

Primeiro, obtemos o estado e o atualizador de estado usando o gancho useState. Em seguida, definimos uma função toggler que define o toggleValue como o oposto do seu valor atual. Por fim, retornamos uma matriz de dois itens, primeiro é toggleValue para ler o estado atual e o próximo é toggler para alternar o estado toggleValue .

Embora a criação de funções em cada renderização não seja lenta em navegadores modernos , podemos evitar isso memorizando a função toggler . Para este propósito, o gancho useCallback é útil. Mais detalhes podem ser encontrados aqui .

Link para o código

Ganchos personalizados são usados como qualquer outro gancho. Isso significa que usar o useToggle em nosso componente EditableItem é tão fácil quanto isto:

Link para o código

Vamos ver como o Render Props se compara em relação ao React Hooks:

Reutilização de código com render Props reutilização patternCode com React Custom Hooks

Sem dúvida, a reutilização de código entre componentes é mais fácil com Ganchos Personalizados e também requer menos quantidade de código. Em seguida, aprenderemos a consumir dados de contexto com React Hooks em vez de usar o padrão Render Props.

Usando Reacts Ganchos para Consumir Dados de Contexto

Assim como temos o gancho useState para state, temos useContext para consumir dados de contexto. Mais uma vez, vamos tentar aprendê-lo usando-o em um cenário prático. Bem, é um requisito comum ter os detalhes do usuário disponíveis nos componentes. Este é um ótimo caso de uso para ganchos de contexto:

Use o contexto para mudar o usuário (clique aqui para vídeo)

Aqui temos dois componentes UserProfile e ChangeProfile . O componente UserProfile mostra os detalhes do usuário e o componente ChangeProfile é usado para alternar entre usuários.

Nota – A troca entre a parte dos usuários é apenas para a nossa demonstração. Em projetos reais, em vez do menu "Selecionar", atualizaremos os detalhes do usuário com base em quem faz login.

A implementação pode ser assim:

Fizemos um componente separado chamado Usuário para armazenar o estado do usuário e fornecer dados e método de atualização de dados para UserContext.Provider . Estes são então consumidos pelos seus componentes filhos, UserProfile e ChangeProfile . O componente UserProfile só precisa ler os detalhes do usuário para que possamos apenas desestruturar o primeiro item da matriz retornada por useContext .

O componente ChangeProfile tem uma matriz de perfis. Quando o usuário seleciona um perfil, atualizamos o UserContext usando o método setUser fornecido pelo próprio UserContext . Este exemplo é suficiente para mostrar que o uso do contexto também é muito simples com ganchos personalizados.

Há mais uma coisa pela qual as pessoas às vezes usam o padrão Render Props. Isso é para implementar slots em seus componentes como este:

Link para o código

Bem, existe uma maneira mais simples, que não precisa de funções como adereços. Podemos apenas atribuir o JSX como componente adjunto como este:

Link para o código

Usar o padrão Render Props aqui seria um erro, pois seu uso pretendido é compartilhar dados entre componentes. Então, nesse caso, devemos evitar usar o Render Props.

Minha opinião pessoal é que o padrão Render Props não foi destinado aos casos de uso acima, mas a comunidade teve que usá-lo porque não havia outro jeito. É ótimo que a equipe do React tenha tomado nota e feito algo que todos nós adoraríamos usar. Ganchos e Render Props podem coexistir porque cada um tem um papel diferente. Michael Chan fez um vídeo explicando isso.

Conclusão

É claro que o futuro do React é muito brilhante. O foco da equipe do React é cristalino. Se alguém souber de outros casos de uso para Render Props, deixe-me saber, eu certamente os mencionarei no artigo.

Se você gosta do meu trabalho, por favor, siga-me no Twitter e Medium ou assine a minha newsletter .

Plug: LogRocket , um DVR para aplicativos da web

https://logrocket.com/signup/

LogRocket é uma ferramenta de registro de front-end que permite que você repita problemas como se eles tivessem ocorrido em seu próprio navegador. Em vez de adivinhar por que os erros ocorrem ou solicitar aos usuários capturas de tela e log dumps, o LogRocket permite que você repita a sessão para entender rapidamente o que deu errado. Ele funciona perfeitamente com qualquer aplicativo, independentemente do framework, e possui plugins para registrar o contexto adicional do Redux, Vuex e @ ngrx / store.

Além de registrar as ações e o estado do Redux, o LogRocket registra logs do console, erros de JavaScript, rastreamentos de pilha, solicitações / respostas de rede com cabeçalhos + corpos, metadados do navegador e logs personalizados. Ele também instrumenta o DOM para gravar o HTML e CSS na página, recriando vídeos com pixels perfeitos até mesmo dos aplicativos de página única mais complexos.

Experimente Grátis.