Este post é uma introdução rápida sobre uma maneira de manter seu código Gutenberg nos padrões atuais usando ganchos React. Veremos como isso é benéfico, por que devemos fazê-lo e como.
Hein, ganchos?
Suponho que você já tenha alguma experiência trabalhando com blocos ou plugins Gutenberg um pouco mais complexos que consultam postagens, ou buscam e atualizam o meta do post. E assim trabalhando com [withSelect](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-data/#withSelect)
e/ou [withDispatch](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-data/#withDispatch)
. Estes são componentes de ordem superior no WordPress que permitem que você acesse as lojas do WordPress para buscar ou enviar informações que estão um pouco fora do bloco "normal" ou da edição de posts. Você possivelmente também foi forçado a usar compose
para combinar seus componente com vários componentes de ordem superior. Se seu código estiver usando esses padrões, não se preocupe – eles funcionam perfeitamente bem e continuarão a funcionar! Mas à medida que a tecnologia avança, podemos fazer melhor.
No início de 2019, o React lançou hooks (versão 16.8) – que permitem usar o estado sem usar uma classe e melhorar outros recursos que fornecem um código mais legível e reutilizável. Por exemplo, removendo a necessidade de envolver seu código em componentes de ordem superior para acessar os registros. E no verão de 2019 o WordPress seguiu, lançando ganchos personalizados: [useDispatch](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-data/#useDispatch)
e [useSelect](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-data/#useSelect)
.
Os benefícios dos ganchos são muitos. O exemplo mais comum é permitir usar o estado do componente sem ter que escrever uma classe Javascript (useState
). Mas, na minha opinião, o maior benefício é a reutilização. Ao remover a necessidade de usar padrões como props de renderização e componentes de ordem superior, os componentes podem ser escritos em partes muito mais independentes. Outro benefício dos ganchos é que eles tornam seu código mais fácil de ler e entender!
Vamos pular direto para alguns exemplos e ver como implementar useSelect
e useDispatch
ganchos em nosso código!
ImplementaçãouseSelect
Vamos começar com withSelect
e seu gancho correspondente useSelect
. Eles são usados para obter props derivadas de estado de seletores registrados. Exemplos comuns são acessar os seletores ‘ core
‘ ou ‘ core/editor
‘ para realizar consultas de postagens (getEntityRecords
), acessar o meta do post (getEditedPostAttribute
) ou simplesmente obter o tipo de postagem atual ou outras informações.
Para fins de demonstração, começarei com um exemplo simples. Suponha que eu tenha um componente de bloco onde eu tenha um seletor de postagem em algum lugar. Para preencher as opções de postagem preciso acessar o registro ‘ core
‘ e realizar uma GetEntityRecords()
chamada.
Maneira antiga usandowithSelect
Se eu quiser consultar postagens em um bloco, precisaria envolver meu componente em withSelect
. Isso é comumente feito na export
declaração.
Observe que este exemplo de código não está completo como um bloco funcional real ou plug-in JS, ele foi removido apenas para mostrar os conceitos principais do withSelect
. Se você estiver procurando por exemplos práticos de código, tenho outros artigos que abordam isso: por exemplo , como implementar blocos com um post select, ou como adicionar post meta ao inspector. Esses são escritos com withSelect
e withDispatch
, assim como aqueles, e depois volte aqui para aprender como transformá-los em ganchos.
Como você pode ver na linha, #12-16
eu envolvo meu componente com withSelect
. Dentro da função withSelect posso acessar a loja que quero, e retorno uma consulta post na prop ” somePosts
“. Esta prop estará então disponível dentro do meu AWP_Example_Plugin
componente (como você pode ver, eu destruo somePosts
as props em line #3
).
Como mencionado anteriormente, esse método funciona muito bem – e continuará a fazê-lo. Mas há várias desvantagens com isso. Uma é que isso não é muito fácil de entender. Claro, este foi um exemplo muito simples. À primeira vista, no próprio componente, você não tem certeza de onde somePosts
vem o suporte ou o que é. Você teria que saber para procurar a instrução de exportação e ver se há algum wrapper. Também se sente um pouco desconexo. Você faz uma grande parte do trabalho importante fora do seu componente, para algo que você realmente deseja disponível dentro do seu componente.
Vamos fazê-lo melhor usando ganchos.
Convertendo emuseSelect
Converter um withSelect
em useSelect
é o mais simples possível. O primeiro passo é que podemos definir a variável somePosts
dentro do nosso componente, ao invés de fora pela export
declaração. O segundo passo é mover toda a função que tínhamos withSelect
para o useSelect
. E é isso.
O código acima fornece exatamente o mesmo resultado que aquele com withSelect
. A diferença é que o código agora é muito mais compreensível! Agora podemos ver muito facilmente que a variável somePosts
está armazenando o resultado de uma consulta post, bem dentro do nosso componente.
Nota importante: useSelect
aceita um segundo parâmetro; uma série de dependências. As dependências são variáveis que garantem a execução apenas useSelect
quando uma das dependências (valores de variável) for alterada. Este bit é mais importante do useDispatch
que aqui, então vou explicar este bit mais na useDispatch
seção abaixo.
ImplementaçãouseDispatch
Agora vamos ver withDispatch
e seu gancho correspondente useDispatch
. Eles são usados para enviar adereços para registros. Por exemplo, dizendo ao Gutenberg para atualizar uma meta de postagem via ‘ core/editor
‘.
Novamente, para fins de demonstração, meus exemplos de código não são partes funcionais completas de código – eles ilustram apenas as partes relacionadas a esses padrões. Neste exemplo, suponho que tenho um campo de texto mostrando uma meta de postagem – e desejo atualizar o valor meta da postagem na alteração.
Maneira antiga usandowithDispatch
Como withDispatch
é um componente de ordem superior, eu precisaria envolver meu componente dentro disso. Isso é comumente feito na export
declaração. Para fazer o campo de texto para o nosso meta-trabalho,
Por exemplo:
Na linha #20-26
envolvemos o componente dentro withDispatch
de, no qual retornamos uma função ” setPostMeta
" que despacha o post meta (para atualizá-lo). Na linha #6
nós desestruturamos a prop para que possamos usá-la no onChange
evento do campo de texto na linha #13
. (Observe que o exemplo acima não seria funcional porque definimos o valor do campo de texto como uma string vazia. Isso é apenas para demonstrar como usaríamos o dispatch).
Novamente, podemos ver que o código não é tão simples de entender. Você teria que saber procurar o wrapper para descobrir o que o prop ” setPostMeta
” é ou de onde vem. Vamos fazer melhor usando ganchos!
Convertendo emuseDispatch
Mudar withDispatch
para useDispatch
não é tão simples quanto converter withSelect
para useSelect
. Ainda é muito fácil embora. Há duas coisas para manter em mente. Uma é que useDispatch
leva um nome de loja como primeiro parâmetro. Nós então acessaríamos a loja e chamaríamos suas funções disponíveis quando a usarmos (por exemplo, em um onChange
evento de campo de texto). Em segundo lugar, a matriz de dependências do useDispatch
segundo parâmetro de é mais importante do que com useSelect
. Você pode arriscar que seu código acabe em um loop eterno se não gerenciar as dependências corretamente. Somente quando as variáveis de dependência forem alteradas, o script será executado novamente useDispatch
.
Por exemplo:
Na linha #8
desestruturamos o que precisamos da loja’ core/editor
‘. Estamos interessados apenas na editPost
função que podemos usar para atualizar o post meta. Como segundo parâmetro para useDispatch
fornecermos dependências. Quanto a um exemplo de atualização do post meta, usar o valor do post meta (usando useSelect
) seria perfeito como dependência. Neste exemplo, acabei de defini-lo como uma variável fictícia. Olhe mais para baixo para um exemplo mais completo e realista. E então na linha #16
do evento do campo de texto onChange
, chamamos editPost
para atualizar o meta. Observe a diferença nesta linha com o uso withDispatch
acima! Como usamos editPost
diretamente em vez de retornar uma função para atualizar post meta para nós (setPostMeta
), precisamos fornecer um objeto commeta
como chave e depois um objeto com a meta do post que queremos atualizar. Nós meio que dividimos o withDispatch
código em pedaços.
Ainda assim, o uso useDispatch
torna o código muito mais legível e compreensível. Não há mais código adicionado fora do nosso componente que precisamos usar dentro.
Um exemplo mais completo e eliminando a necessidade decompose
Provavelmente, se você estiver usando withDispatch
, precisará withSelect
desse componente também. Nos exemplos para conversão useDispatch
acima, estamos atualizando um valor meta post. Mas para que o campo de texto funcione corretamente (e também mostre o valor atual), também precisaríamos buscar o valor meta do post.
Se você precisar usar vários componentes de ordem superior agrupados em seu componente, provavelmente usará outra função do Gutenberg; [compose](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-compose/)
. É uma função útil para combinar vários componentes de ordem superior em um componente de ordem superior que você pode envolver seu componente.
Vejamos um exemplo mais completo de um componente que busca um meta valor de postagem em um campo de texto e atualiza quando seu valor é alterado. Começamos com como teríamos que fazer isso usando withSelect
e withDispatch
(e, portanto, também compose
).
Usando withSelect
, withDispatch
ecompose
Na linha #21-34
, compomos withSelect
e withDispatch
os envolvemos em torno de nosso componente. postMeta
from withSelect
e setPostMeta
from withDispatch
estão agora disponíveis em nosso componente como adereços. Nós os desestruturamos na linha #7
e os usamos em #13
e #14
.
Como você pode ver, o código necessário fora do nosso componente é maior que o próprio componente. Não sei quanto a você, mas para mim parece um pouco desconexo. Os desenvolvedores podem começar a ler esse código de cima, sem ver a parte de baixo, e começar a se perguntar de onde postMeta
e de onde setPostMeta
vêm – eles parecem estar magicamente disponíveis. Para mim isso é muito pouco intuitivo.
Vejamos como converteríamos o exemplo acima em ganchos.
Usando useSelect
euseDispatch
Quão bonito e legível é isso?! Podemos ver imediatamente em nosso componente postMeta
de onde é obtido e como obtemos acesso ao editPost
. Nosso componente também ficou muito mais fácil de reutilizar.
Observe que na useDispatch
linha at #12
adicionamos o postmeta que estamos atualizando como dependência (postMeta.example_post_meta
). Se você mantivesse várias variáveis meta do post atualizadas neste componente, você teria que adicionar cada uma como uma dependência para garantir que o dispatch seja executado (na verdade salvando o meta do post) quando o valor de uma delas for alterado.
Espero que isso tenha sido informativo e útil para alguém lá fora. Ainda não estou familiarizado com os ganchos, mas vendo os benefícios de usá-los não vou voltar atrás!