* Update Docs CI with mdbook translation support #514 * install mdbook with --rev
5.1 KiB
Hooks e Estado do Componente
Até agora nossos componentes, sendo funções Rust, não tinham estado – eles estavam sempre renderizando a mesma coisa. No entanto, em um componente de interface do usuário, geralmente é útil ter uma funcionalidade com estado para criar interações do usuário. Por exemplo, você pode querer rastrear se o usuário abriu uma lista suspensa e renderizar coisas diferentes de acordo.
Para lógica com estado, você pode usar hooks. Hooks são funções Rust que fazem referência a ScopeState (em um componente, você pode passar &cx), e fornecem funcionalidade e estado.
Hook use_state
use_state é um dos hooks mais simples.
- Você fornece um fechamento que determina o valor inicial
use_statefornece o valor atual e uma maneira de atualizá-lo, definindo-o para outra coisa- Quando o valor é atualizado,
use_statefaz o componente renderizar novamente e fornece o novo valor
Por exemplo, você pode ter visto o exemplo do contador, no qual o estado (um número) é rastreado usando o hook use_state:
{{#include ../../../examples/hooks_counter.rs:component}}
Toda vez que o estado do componente muda, ele é renderizado novamente e a função do componente é chamada, para que você possa descrever como deseja que a nova interface do usuário se pareça. Você não precisa se preocupar em "mudar" nada - apenas descreva o que você quer em termos de estado, e Dioxus cuidará do resto!
use_stateretorna seu valor envolto em uma smart pointer do tipoUseState. É por isso que você pode ler o valor e atualizá-lo, mesmo dentro de um manipulador.
Você pode usar vários hooks no mesmo componente se quiser:
{{#include ../../../examples/hooks_counter_two_state.rs:component}}
Regras dos Hooks
O exemplo acima pode parecer um pouco mágico, já que as funções Rust normalmente não estão associadas ao estado. O Dioxus permite que os hooks mantenham o estado entre as renderizações através de uma referência a ScopeState, e é por isso que você deve passar &cx para eles.
Mas como Dioxus pode diferenciar entre vários hooks no mesmo componente? Como você viu no segundo exemplo, ambas as funções use_state foram chamadas com os mesmos parâmetros, então como elas podem retornar coisas diferentes quando os contadores são diferentes?
{{#include ../../../examples/hooks_counter_two_state.rs:use_state_calls}}
Isso só é possível porque os dois hooks são sempre chamados na mesma ordem, então Dioxus sabe qual é qual. Portanto, a ordem em que você chama os hooks é importante, e é por isso que você deve seguir certas regras ao usar os hooks:
- Hooks só podem ser usados em componentes ou outros hooks (falaremos disso mais tarde)
- Em cada chamada para a função componente
- Os mesmos hooks devem ser chamados
- Na mesma ordem
- Os nomes dos hooks devem começar com
use_para que você não os confunda acidentalmente com funções normais
Essas regras significam que há certas coisas que você não pode fazer com hooks:
Sem Hooks em Condicionais
{{#include ../../../examples/hooks_bad.rs:conditional}}
Sem Hooks em Closures
{{#include ../../../examples/hooks_bad.rs:closure}}
Sem Hooks em Loops
{{#include ../../../examples/hooks_bad.rs:loop}}
Gancho use_ref
use_state é ótimo para rastrear valores simples. No entanto, você pode notar na UseState API que a única maneira de modificar seu valor é substituí-lo por algo else (por exemplo, chamando set, ou através de um dos operadores +=, -=). Isso funciona bem quando é barato construir um valor (como qualquer primitivo). Mas e se você quiser manter dados mais complexos no estado dos componentes?
Por exemplo, suponha que queremos manter um Vec de valores. Se o armazenamos com use_state, a única maneira de adicionar um novo valor à lista seria criar um novo Vec com o valor adicional e colocá-lo no estado. Isto é custoso! Queremos modificar o Vec existente.
Felizmente, existe outro hook para isso, use_ref! É semelhante ao use_state, mas permite obter uma referência mutável aos dados contidos.
Aqui está um exemplo simples que mantém uma lista de eventos em um use_ref. Podemos adquirir acesso de escrita ao estado com .write(), e então apenas .push um novo valor para o estado:
{{#include ../../../examples/hooks_use_ref.rs:component}}
Os valores de retorno de
use_stateeuse_ref, (UseStateeUseRef, respectivamente) são de alguma forma semelhantes a [Cell](https://doc.rust-lang.org/std/ cell/) eRefCell– eles fornecem mutabilidade interior. No entanto, esses wrappers do Dioxus também garantem que o componente seja renderizado novamente sempre que você alterar o estado.

