Merge branch 'master' into master
This commit is contained in:
313 files changed
+23988
-2334
No files matched your search
@@ -2,7 +2,7 @@
|
||||
|
||||
Os **"hooks"** `use_future` e `use_coroutine` são úteis se você quiser gerar incondicionalmente o `Future`. Às vezes, porém, você desejará apenas gerar um `Future` em resposta a um evento, como um clique do mouse. Por exemplo, suponha que você precise enviar uma solicitação quando o usuário clicar em um botão "log in". Para isso, você pode usar `cx.spawn`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/spawn.rs:spawn}}
|
||||
```
|
||||
|
||||
@@ -14,7 +14,7 @@ No entanto, como você normalmente precisa de uma maneira de atualizar o valor d
|
||||
|
||||
Para tornar isso um pouco menos detalhado, o Dioxus exporta a macro `to_owned!` que criará uma ligação como mostrado acima, o que pode ser bastante útil ao lidar com muitos valores.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/spawn.rs:to_owned_macro}}
|
||||
```
|
||||
|
||||
@@ -24,6 +24,6 @@ Calling `spawn` will give you a `JoinHandle` which lets you cancel or pause the
|
||||
|
||||
Às vezes, você pode querer gerar uma tarefa em segundo plano que precise de vários _threads_ ou conversar com o hardware que pode bloquear o código do seu aplicativo. Nesses casos, podemos gerar diretamente uma tarefa Tokio do nosso `Future`. Para Dioxus-Desktop, sua tarefa será gerada no tempo de execução Multi-Tarefado do Tokio:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/spawn.rs:tokio}}
|
||||
```
|
||||
@@ -8,7 +8,7 @@ Assim como os `Futures` regulares, o código em uma corrotina Dioxus será execu
|
||||
|
||||
A configuração básica para corrotinas é o _hook_ `use_coroutine`. A maioria das corrotinas que escrevemos serão _loops_ de pesquisa usando `async`/`await`.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn app(cx: Scope) -> Element {
|
||||
let ws: &UseCoroutine<()> = use_coroutine(cx, |rx| async move {
|
||||
// Connect to some sort of service
|
||||
@@ -26,7 +26,7 @@ Para muitos serviços, um _loop_ assíncrono simples lidará com a maioria dos c
|
||||
|
||||
No entanto, se quisermos desabilitar temporariamente a corrotina, podemos "pausá-la" usando o método `pause` e "retomá-la" usando o método `resume`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
let sync: &UseCoroutine<()> = use_coroutine(cx, |rx| async move {
|
||||
// code for syncing
|
||||
});
|
||||
@@ -56,7 +56,7 @@ Você deve ter notado que o encerramento `use_coroutine` recebe um argumento cha
|
||||
|
||||
Usando corrotinas, temos a oportunidade de centralizar nossa lógica assíncrona. O parâmetro `rx` é um canal ilimitado para código externo à corrotina para enviar dados _para_ a corrotina. Em vez de fazer um _loop_ em um serviço externo, podemos fazer um _loop_ no próprio canal, processando mensagens de dentro de nosso aplicativo sem precisar gerar um novo `Future`. Para enviar dados para a corrotina, chamaríamos "send" no _handle_.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
enum ProfileUpdate {
|
||||
SetUsername(String),
|
||||
SetAge(i32)
|
||||
@@ -84,7 +84,7 @@ cx.render(rsx!{
|
||||
|
||||
Para aplicativos suficientemente complexos, poderíamos criar vários "serviços" úteis diferentes que fazem um _loop_ nos canais para atualizar o aplicativo.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
let profile = use_coroutine(cx, profile_service);
|
||||
let editor = use_coroutine(cx, editor_service);
|
||||
let sync = use_coroutine(cx, sync_service);
|
||||
@@ -104,7 +104,7 @@ async fn editor_service(rx: UnboundedReceiver<EditorCommand>) {
|
||||
|
||||
Podemos combinar corrotinas com `Fermi` para emular o sistema `Thunk` do **Redux Toolkit** com muito menos dor de cabeça. Isso nos permite armazenar todo o estado do nosso aplicativo _dentro_ de uma tarefa e, em seguida, simplesmente atualizar os valores de "visualização" armazenados em `Atoms`. Não pode ser subestimado o quão poderosa é essa técnica: temos todas as vantagens das tarefas nativas do Rust com as otimizações e ergonomia do estado global. Isso significa que seu estado _real_ não precisa estar vinculado a um sistema como `Fermi` ou `Redux` – os únicos `Atoms` que precisam existir são aqueles que são usados para controlar a interface.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
static USERNAME: Atom<String> = Atom(|_| "default".to_string());
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
@@ -128,7 +128,7 @@ fn Banner(cx: Scope) -> Element {
|
||||
|
||||
Agora, em nosso serviço de sincronização, podemos estruturar nosso estado como quisermos. Só precisamos atualizar os valores da _view_ quando estiver pronto.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
enum SyncAction {
|
||||
SetUsername(String),
|
||||
}
|
||||
@@ -155,7 +155,7 @@ async fn sync_service(mut rx: UnboundedReceiver<SyncAction>, atoms: AtomRoot) {
|
||||
|
||||
Para obter valores de uma corrotina, basta usar um identificador `UseState` e definir o valor sempre que sua corrotina concluir seu trabalho.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
let sync_status = use_state(cx, || Status::Launching);
|
||||
let sync_task = use_coroutine(cx, |rx: UnboundedReceiver<SyncAction>| {
|
||||
to_owned![sync_status];
|
||||
@@ -172,7 +172,7 @@ let sync_task = use_coroutine(cx, |rx: UnboundedReceiver<SyncAction>| {
|
||||
|
||||
Os identificadores de corrotina são injetados automaticamente por meio da API de contexto. `use_coroutine_handle` com o tipo de mensagem como genérico pode ser usado para buscar um _handle_.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn Child(cx: Scope) -> Element {
|
||||
let sync_task = use_coroutine_handle::<SyncAction>(cx);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Por exemplo, podemos fazer uma solicitação de API dentro de `use_future`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/use_future.rs:use_future}}
|
||||
```
|
||||
|
||||
@@ -14,7 +14,7 @@ Podemos usar `.value()` para obter o resultado do `Future`. Na primeira execuç
|
||||
|
||||
Podemos então renderizar esse resultado:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/use_future.rs:render}}
|
||||
```
|
||||
|
||||
@@ -26,6 +26,6 @@ O identificador `UseFuture` fornece um método `restart`. Ele pode ser usado par
|
||||
|
||||
Muitas vezes, você precisará executar o `Future` novamente toda vez que algum valor (por exemplo, uma prop) mudar. Ao invés de `.restart` manualmente, você pode fornecer uma tupla de "dependências" para o gancho. Ele executará automaticamente o `Future` quando qualquer uma dessas dependências for alterada. Exemplo:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/use_future.rs:dependency}}
|
||||
```
|
||||
@@ -8,7 +8,7 @@ Os fragmentos não montam um elemento físico no DOM imediatamente, então o Dio
|
||||
|
||||
Apenas os nós Componente e Fragmento são suscetíveis a esse problema. O Dioxus atenua isso com componentes fornecendo uma API para registrar o estado compartilhado sem o padrão _Context Provider_.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/anti_patterns.rs:nested_fragments}}
|
||||
```
|
||||
|
||||
@@ -16,7 +16,7 @@ Apenas os nós Componente e Fragmento são suscetíveis a esse problema. O Dioxu
|
||||
|
||||
Conforme descrito no capítulo de renderização condicional, os itens da lista devem ter _keys_ exclusivas associadas aos mesmos itens nas renderizações. Isso ajuda o Dioxus a associar o estado aos componentes contidos e garante um bom desempenho de diferenciação. Não omita as _keys_, a menos que você saiba que a lista é estática e nunca será alterada.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/anti_patterns.rs:iter_keys}}
|
||||
```
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ No entanto, não falamos sobre tratamento de erros neste guia! Neste capítulo,
|
||||
|
||||
Observadores astutos podem ter notado que `Element` é na verdade um alias de tipo para `Option<VNode>`. Você não precisa saber o que é um `VNode`, mas é importante reconhecer que não poderíamos retornar nada:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn App(cx: Scope) -> Element {
|
||||
None
|
||||
}
|
||||
@@ -18,7 +18,7 @@ Isso nos permite adicionar um pouco de açúcar sintático para operações que
|
||||
|
||||
> A natureza de `Option<VNode>` pode mudar no futuro à medida que a característica `try` for atualizada.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn App(cx: Scope) -> Element {
|
||||
// immediately return "None"
|
||||
let name = cx.use_hook(|_| Some("hi"))?;
|
||||
@@ -29,7 +29,7 @@ fn App(cx: Scope) -> Element {
|
||||
|
||||
Como o Rust não pode aceitar opções e resultados com a infraestrutura _try_ existente, você precisará manipular os resultados manualmente. Isso pode ser feito convertendo-os em `Option` ou manipulando-os explicitamente.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn App(cx: Scope) -> Element {
|
||||
// Convert Result to Option
|
||||
let name = cx.use_hook(|_| "1.234").parse().ok()?;
|
||||
@@ -52,13 +52,13 @@ A próxima "melhor" maneira de lidar com erros no Dioxus é combinar (`match`) o
|
||||
|
||||
Para fazer isso, simplesmente temos um estado de erro embutido em nosso componente:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
let err = use_state(cx, || None);
|
||||
```
|
||||
|
||||
Sempre que realizarmos uma ação que gere um erro, definiremos esse estado de erro. Podemos então combinar o erro de várias maneiras (retorno antecipado, elemento de retorno etc.).
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn Commandline(cx: Scope) -> Element {
|
||||
let error = use_state(cx, || None);
|
||||
|
||||
@@ -79,7 +79,7 @@ fn Commandline(cx: Scope) -> Element {
|
||||
|
||||
Se você estiver lidando com alguns componentes com um mínimo de aninhamento, basta passar o identificador de erro para componentes filhos.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn Commandline(cx: Scope) -> Element {
|
||||
let error = use_state(cx, || None);
|
||||
|
||||
@@ -106,7 +106,7 @@ Para começar, considere usar um _hook_ embutido como `use_context` e `use_conte
|
||||
|
||||
No "topo" de nossa arquitetura, queremos declarar explicitamente um valor que pode ser um erro.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
enum InputError {
|
||||
None,
|
||||
TooLong,
|
||||
@@ -118,7 +118,7 @@ static INPUT_ERROR: Atom<InputError> = Atom(|_| InputError::None);
|
||||
|
||||
Então, em nosso componente de nível superior, queremos tratar explicitamente o possível estado de erro para esta parte da árvore.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn TopLevel(cx: Scope) -> Element {
|
||||
let error = use_read(cx, &INPUT_ERROR);
|
||||
|
||||
@@ -132,7 +132,7 @@ fn TopLevel(cx: Scope) -> Element {
|
||||
|
||||
Agora, sempre que um componente _downstream_ tiver um erro em suas ações, ele pode simplesmente definir seu próprio estado de erro:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn Commandline(cx: Scope) -> Element {
|
||||
let set_error = use_set(cx, &INPUT_ERROR);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ Como referência, confira o interpretador `javascript` ou o renderizador `tui` c
|
||||
|
||||
O tipo "DomEdit" é uma `enum` serializada que representa uma operação atômica que ocorre no `RealDom`. As variantes seguem aproximadamente este conjunto:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
enum DomEdit {
|
||||
PushRoot,
|
||||
AppendChildren,
|
||||
@@ -48,7 +48,7 @@ O mecanismo de diferenciação Dioxus opera como uma [máquina de pilha] (https:
|
||||
|
||||
Para fins de compreensão, vamos considerar este exemplo – uma declaração de interface do usuário muito simples:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
rsx!( h1 {"hello world"} )
|
||||
```
|
||||
|
||||
@@ -56,7 +56,7 @@ Para começar, o Dioxus deve primeiro navegar até o contêiner dessa tag h1. Pa
|
||||
|
||||
Quando o renderizador recebe essa instrução, ele empurra o `Node` real para sua própria pilha. A pilha do renderizador real ficará assim:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
instructions: [
|
||||
PushRoot(Container)
|
||||
]
|
||||
@@ -67,7 +67,7 @@ stack: [
|
||||
|
||||
Em seguida, o Dioxus encontrará o nó `h1`. O algoritmo `diff` decide que este nó precisa ser criado, então o Dioxus irá gerar o DomEdit `CreateElement`. Quando o renderizador receber esta instrução, ele criará um nó desmontado e o enviará para sua própria pilha (_stack_):
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
instructions: [
|
||||
PushRoot(Container),
|
||||
CreateElement(h1),
|
||||
@@ -80,7 +80,7 @@ stack: [
|
||||
|
||||
Em seguida, Dioxus vê o nó de texto e gera o DomEdit `CreateTextNode`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
instructions: [
|
||||
PushRoot(Container),
|
||||
CreateElement(h1),
|
||||
@@ -95,7 +95,7 @@ stack: [
|
||||
|
||||
Lembre-se, o nó de texto não está anexado a nada (ele está desmontado), então o Dioxus precisa gerar um _Edit_ que conecte o nó de texto ao elemento `h1`. Depende da situação, mas neste caso usamos `AppendChildren`. Isso remove o nó de texto da _stack_, deixando o elemento `h1` como o próximo elemento na linha.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
instructions: [
|
||||
PushRoot(Container),
|
||||
CreateElement(h1),
|
||||
@@ -110,7 +110,7 @@ stack: [
|
||||
|
||||
Chamamos `AppendChildren` novamente, retirando o nó `h1` e anexando-o ao pai:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
instructions: [
|
||||
PushRoot(Container),
|
||||
CreateElement(h1),
|
||||
@@ -125,7 +125,7 @@ stack: [
|
||||
|
||||
Finalmente, o contêiner é aberto, pois não precisamos mais dele.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
instructions: [
|
||||
PushRoot(Container),
|
||||
CreateElement(h1),
|
||||
@@ -139,7 +139,7 @@ stack: []
|
||||
|
||||
Com o tempo, nossa _stack_ ficou assim:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
[]
|
||||
[Container]
|
||||
[Container, h1]
|
||||
@@ -165,7 +165,7 @@ Como a maioria das GUIs, o Dioxus conta com um _loop_ de eventos para progredir
|
||||
|
||||
O código para a implementação do `WebSys` é direto, então vamos adicioná-lo aqui para demonstrar como um `loop` de eventos é simples:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
pub async fn run(&mut self) -> dioxus_core::error::Result<()> {
|
||||
// Push the body element onto the WebsysDom's stack machine
|
||||
let mut websys_dom = crate::new::WebsysDom::new(prepare_websys_dom());
|
||||
@@ -195,7 +195,7 @@ pub async fn run(&mut self) -> dioxus_core::error::Result<()> {
|
||||
|
||||
É importante que você decodifique os eventos reais do seu sistema de eventos no sistema de eventos sintético do Dioxus (entenda sintético como abstraído). Isso significa simplesmente combinar seu tipo de evento e criar um tipo Dioxus `UserEvent`. No momento, o sistema `VirtualEvent` é modelado quase inteiramente em torno da especificação HTML, mas estamos interessados em reduzi-lo.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent {
|
||||
match event.type_().as_str() {
|
||||
"keydown" => {
|
||||
@@ -233,7 +233,7 @@ Esses elementos personalizados são definidos como estruturas de unidade com imp
|
||||
|
||||
Por exemplo, o elemento `div` é (aproximadamente!) definido assim:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
struct div;
|
||||
impl div {
|
||||
/// Some glorious documentation about the class property.
|
||||
@@ -262,7 +262,7 @@ O `RealDom` é uma abstração de nível superior sobre a atualização do Dom.
|
||||
Vamos construir um renderizador de exemplo com bordas, tamanho e cor do texto.
|
||||
Antes de começarmos, vamos dar uma olhada em um elemento de exemplo que podemos renderizar:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
cx.render(rsx!{
|
||||
div{
|
||||
color: "red",
|
||||
@@ -280,50 +280,50 @@ No diagrama a seguir, as setas representam o fluxo de dados:
|
||||
|
||||
[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqdVNFqgzAU_RXJXizUUZPJmIM-jO0LukdhpCbO0JhIGteW0n9fNK1Oa0brfUnu9VxyzzkXjyCVhIIYZFzu0hwr7X2-JcIzsa3W3wqXuZdKoele22oddfa1Y0Tnfn31muvMfqeCDNq3GmvaNROmaKqZFO1DPTRhP8MOd1fTWYNDvzlmQbBMJZcq9JtjNgY1mLVUhBqQPQeojl3wGCw5PsjqnIe-zXqEL8GZ2Kz0gVMPmoeU3ND4IcuiaLGY2zRouuKncv_qGKv3VodpJe0JVU6QCQ5kgqMyWQVr8hbk4hm1PBcmsuwmnrCVH94rP7xN_ucp8sOB_EPSfz9drYVrkpc_AmH8_yTjJueUc-ntpOJkgt2os9tKjcYlt-DLUiD3UsB2KZCLcwjv3Aq33-g2v0M0xXA0MBy5DUdXi-gcJZriuLmAOSioKjAj5ld8rMsJ0DktaAJicyVYbRKQiJPBVSUx438QpqUCcYb5ls4BrrRcHUTaFizqnWGzR8W5evoFI-bJdw)
|
||||
|
||||
[//]: # '%% mermaid flow chart'
|
||||
[//]: # 'flowchart TB'
|
||||
[//]: # ' subgraph context'
|
||||
[//]: # ' text_width(text width)'
|
||||
[//]: # ' end'
|
||||
[//]: # ' subgraph state'
|
||||
[//]: # ' direction TB'
|
||||
[//]: # ' subgraph div state'
|
||||
[//]: # ' direction TB'
|
||||
[//]: # ' state1(state)-->color1(color)'
|
||||
[//]: # ' state1-->border1(border)'
|
||||
[//]: # ' text_width-.->layout_width1(layout width)'
|
||||
[//]: # ' linkStyle 2 stroke:#ff5500,stroke-width:4px;'
|
||||
[//]: # ' state1-->layout_width1'
|
||||
[//]: # ' end'
|
||||
[//]: # ' subgraph p state'
|
||||
[//]: # ' direction TB'
|
||||
[//]: # ' state2(state)-->color2(color)'
|
||||
[//]: # ' color1-.->color2'
|
||||
[//]: # ' linkStyle 5 stroke:#0000ff,stroke-width:4px;'
|
||||
[//]: # ' state2-->border2(border)'
|
||||
[//]: # ' text_width-.->layout_width2(layout width)'
|
||||
[//]: # ' linkStyle 7 stroke:#ff5500,stroke-width:4px;'
|
||||
[//]: # ' state2-->layout_width2'
|
||||
[//]: # ' layout_width2-.->layout_width1'
|
||||
[//]: # ' linkStyle 9 stroke:#00aa00,stroke-width:4px;'
|
||||
[//]: # ' end'
|
||||
[//]: # ' subgraph hello world state'
|
||||
[//]: # ' direction TB'
|
||||
[//]: # ' state3(state)-->border3(border)'
|
||||
[//]: # ' state3-->color3(color)'
|
||||
[//]: # ' color2-.->color3'
|
||||
[//]: # ' linkStyle 12 stroke:#0000ff,stroke-width:4px;'
|
||||
[//]: # ' text_width-.->layout_width3(layout width)'
|
||||
[//]: # ' linkStyle 13 stroke:#ff5500,stroke-width:4px;'
|
||||
[//]: # ' state3-->layout_width3'
|
||||
[//]: # ' layout_width3-.->layout_width2'
|
||||
[//]: # ' linkStyle 15 stroke:#00aa00,stroke-width:4px;'
|
||||
[//]: # ' end'
|
||||
[//]: # ' end'
|
||||
[//]: # "%% mermaid flow chart"
|
||||
[//]: # "flowchart TB"
|
||||
[//]: # " subgraph context"
|
||||
[//]: # " text_width(text width)"
|
||||
[//]: # " end"
|
||||
[//]: # " subgraph state"
|
||||
[//]: # " direction TB"
|
||||
[//]: # " subgraph div state"
|
||||
[//]: # " direction TB"
|
||||
[//]: # " state1(state)-->color1(color)"
|
||||
[//]: # " state1-->border1(border)"
|
||||
[//]: # " text_width-.->layout_width1(layout width)"
|
||||
[//]: # " linkStyle 2 stroke:#ff5500,stroke-width:4px;"
|
||||
[//]: # " state1-->layout_width1"
|
||||
[//]: # " end"
|
||||
[//]: # " subgraph p state"
|
||||
[//]: # " direction TB"
|
||||
[//]: # " state2(state)-->color2(color)"
|
||||
[//]: # " color1-.->color2"
|
||||
[//]: # " linkStyle 5 stroke:#0000ff,stroke-width:4px;"
|
||||
[//]: # " state2-->border2(border)"
|
||||
[//]: # " text_width-.->layout_width2(layout width)"
|
||||
[//]: # " linkStyle 7 stroke:#ff5500,stroke-width:4px;"
|
||||
[//]: # " state2-->layout_width2"
|
||||
[//]: # " layout_width2-.->layout_width1"
|
||||
[//]: # " linkStyle 9 stroke:#00aa00,stroke-width:4px;"
|
||||
[//]: # " end"
|
||||
[//]: # " subgraph hello world state"
|
||||
[//]: # " direction TB"
|
||||
[//]: # " state3(state)-->border3(border)"
|
||||
[//]: # " state3-->color3(color)"
|
||||
[//]: # " color2-.->color3"
|
||||
[//]: # " linkStyle 12 stroke:#0000ff,stroke-width:4px;"
|
||||
[//]: # " text_width-.->layout_width3(layout width)"
|
||||
[//]: # " linkStyle 13 stroke:#ff5500,stroke-width:4px;"
|
||||
[//]: # " state3-->layout_width3"
|
||||
[//]: # " layout_width3-.->layout_width2"
|
||||
[//]: # " linkStyle 15 stroke:#00aa00,stroke-width:4px;"
|
||||
[//]: # " end"
|
||||
[//]: # " end"
|
||||
|
||||
Para ajudar na construção de um DOM, o núcleo nativo fornece quatro `traits`: `State`, `ChildDepState`, `ParentDepState` e `NodeDepState` e uma estrutura `RealDom`. O `ChildDepState`, `ParentDepState` e `NodeDepState` fornecem uma maneira de descrever como algumas informações em um nó se relacionam com as de seus parentes. Ao fornecer como construir um único nó a partir de suas relações, o native-core derivará uma maneira de atualizar o estado de todos os nós para você com `#[derive(State)]`. Depois de ter um estado, você pode fornecê-lo como genérico ao `RealDom`. `RealDom` fornece todos os métodos para interagir e atualizar seu novo dom.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
use dioxus_native_core::node_ref::*;
|
||||
use dioxus_native_core::state::{ChildDepState, NodeDepState, ParentDepState, State};
|
||||
use dioxus_native_core_macro::{sorted_str_slice, State};
|
||||
@@ -455,7 +455,7 @@ struct ToyState {
|
||||
|
||||
Agora que temos nosso estado, podemos colocá-lo em uso em nosso DOM. Você pode atualizar o DOM com `update_state` para atualizar a estrutura do dom (adicionando, removendo e alterando as propriedades dos nós) e então `apply_mutations` para atualizar o `ToyState` para cada um dos nós que foram alterados.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn main(){
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx!{
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
Em alguns casos, você pode desejar criar um componente que atue como um contêiner para algum outro conteúdo, sem que o componente precise saber qual é esse conteúdo. Para conseguir isso, crie uma _prop_ do tipo `Element`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_element_props.rs:Clickable}}
|
||||
```
|
||||
|
||||
Então, ao renderizar o componente, você pode passar a saída de `cx.render(rsx!(...))`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_element_props.rs:Clickable_usage}}
|
||||
```
|
||||
|
||||
@@ -20,12 +20,12 @@ Então, ao renderizar o componente, você pode passar a saída de `cx.render(rsx
|
||||
|
||||
Em vez de passar o `RSX` através de uma _prop_ regular, você pode querer aceitar filhos da mesma forma que os elementos podem ter filhos. O prop "mágico" `children` permite que você consiga isso:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_children.rs:Clickable}}
|
||||
```
|
||||
|
||||
Isso torna o uso do componente muito mais simples: basta colocar o `RSX` dentro dos colchetes `{}` – e não há necessidade de uma chamada `render` ou outra macro!
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_children.rs:Clickable_usage}}
|
||||
```
|
||||
@@ -19,13 +19,13 @@ Existem 2 tipos de estruturas Props:
|
||||
|
||||
_Props_ próprios são muito simples – eles não emprestam nada. Exemplo:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_owned_props.rs:Likes}}
|
||||
```
|
||||
|
||||
Você pode então passar valores de _prop_ para o componente da mesma forma que você passaria atributos para um elemento:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_owned_props.rs:App}}
|
||||
```
|
||||
|
||||
@@ -37,13 +37,13 @@ Possuir _props_ funciona bem se seus _props_ forem fáceis de copiar – como um
|
||||
|
||||
Rust permite algo mais eficiente – emprestar a `String` como um `&str` – é para isso que servem as _props emprestadas_!
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_borrowed_props.rs:TitleCard}}
|
||||
```
|
||||
|
||||
Podemos então usar o componente assim:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_borrowed_props.rs:App}}
|
||||
```
|
||||
|
||||
@@ -57,13 +57,13 @@ A macro `#[derive(Props)]` tem alguns recursos que permitem personalizar o compo
|
||||
|
||||
Você pode criar campos opcionais usando o tipo `Option<…>` para um campo:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:OptionalProps}}
|
||||
```
|
||||
|
||||
Em seguida, você pode optar por fornecê-los ou não:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:OptionalProps_usage}}
|
||||
```
|
||||
|
||||
@@ -71,13 +71,13 @@ Em seguida, você pode optar por fornecê-los ou não:
|
||||
|
||||
Se você quiser exigir explicitamente uma `Option`, e não uma _prop_ opcional, você pode anotá-la com `#[props(!optional)]`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:ExplicitOption}}
|
||||
```
|
||||
|
||||
Então, você tem que passar explicitamente `Some("str")` ou `None`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:ExplicitOption_usage}}
|
||||
```
|
||||
|
||||
@@ -85,13 +85,13 @@ Então, você tem que passar explicitamente `Some("str")` ou `None`:
|
||||
|
||||
Você pode usar `#[props(default = 42)]` para tornar um campo opcional e especificar seu valor padrão:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:DefaultComponent}}
|
||||
```
|
||||
|
||||
Então, da mesma forma que _props_ opcionais, você não precisa fornecê-lo:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:DefaultComponent_usage}}
|
||||
```
|
||||
|
||||
@@ -99,13 +99,13 @@ Então, da mesma forma que _props_ opcionais, você não precisa fornecê-lo:
|
||||
|
||||
É comum que as funções Rust aceitem `impl Into<SomeType>` em vez de apenas `SomeType` para suportar uma ampla gama de parâmetros. Se você quiser uma funcionalidade semelhante com _props_, você pode usar `#[props(into)]`. Por exemplo, você pode adicioná-lo em uma prop `String` – e `&str` também será aceito automaticamente, pois pode ser convertido em `String`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:IntoComponent}}
|
||||
```
|
||||
|
||||
Então, você pode usá-lo assim:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_props_options.rs:IntoComponent_usage}}
|
||||
```
|
||||
|
||||
@@ -115,7 +115,7 @@ Até agora, todas as funções `Component` que vimos tinham uma _struct_ `Compon
|
||||
|
||||
`inline_props` permite que você faça exatamente isso. Em vez de digitar a versão "completa":
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
#[derive(Props, PartialEq)]
|
||||
struct TitleCardProps {
|
||||
title: String,
|
||||
@@ -130,7 +130,7 @@ fn TitleCard(cx: Scope<TitleCardProps>) -> Element {
|
||||
|
||||
...você pode definir uma função que aceita _props_ como argumentos. Então, basta anotá-lo com `#[inline_props]`, e a macro irá transformá-lo em um componente regular para você:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
#[inline_props]
|
||||
fn TitleCard(cx: Scope, title: String) -> Element {
|
||||
cx.render(rsx!{
|
||||
|
||||
@@ -4,7 +4,7 @@ Assim como você não gostaria de escrever um programa complexo em uma única e
|
||||
|
||||
Um componente é uma função Rust, nomeada em _UpperCammelCase_, que recebe um parâmetro `Scope` e retorna um `Element` descrevendo a interface do usuário que deseja renderizar. Na verdade, nossa função `App` é um componente!
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hello_world_desktop.rs:component}}
|
||||
```
|
||||
|
||||
@@ -12,13 +12,13 @@ Um componente é uma função Rust, nomeada em _UpperCammelCase_, que recebe um
|
||||
|
||||
Um Componente é responsável por alguma tarefa de renderização – normalmente, renderizando uma parte isolada da interface do usuário. Por exemplo, você pode ter um componente `About` que renderiza uma breve descrição do Dioxus Labs:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/components.rs:About}}
|
||||
```
|
||||
|
||||
Em seguida, você pode renderizar seu componente em outro componente, da mesma forma que os elementos são renderizados:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/components.rs:App}}
|
||||
```
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Dioxus é uma estrutura _declarativa_. Isso significa que, em vez de dizer ao Di
|
||||
|
||||
Você já viu um exemplo simples ou sintaxe `RSX` no aplicativo "hello world":
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hello_world_desktop.rs:component}}
|
||||
```
|
||||
|
||||
@@ -14,7 +14,7 @@ Aqui, usamos a macro `rsx!` para _declarar_ que queremos um elemento `div`, cont
|
||||
|
||||
O RSX é muito semelhante ao HTML, pois descreve elementos com atributos e filhos. Aqui está um elemento `div` vazio no RSX, bem como o HTML resultante:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:empty}}
|
||||
```
|
||||
|
||||
@@ -26,7 +26,7 @@ O RSX é muito semelhante ao HTML, pois descreve elementos com atributos e filho
|
||||
|
||||
Para adicionar filhos a um elemento, coloque-os dentro dos colchetes `{}`. Eles podem ser outros elementos ou texto. Por exemplo, você pode ter um elemento `ol` (lista ordenada), contendo 3 elementos `li` (item da lista), cada um dos quais contém algum texto:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:children}}
|
||||
```
|
||||
|
||||
@@ -44,7 +44,7 @@ Você também pode "agrupar" elementos envolvendo-os em `Fragment {}`. Isso não
|
||||
|
||||
> Nota: você também pode renderizar vários elementos no nível superior de `rsx!` e eles serão agrupados automaticamente – não há necessidade de um `Fragment {}` explícito lá.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:fragments}}
|
||||
```
|
||||
|
||||
@@ -60,7 +60,7 @@ Você também pode "agrupar" elementos envolvendo-os em `Fragment {}`. Isso não
|
||||
|
||||
Os atributos também são especificados dentro dos colchetes `{}`, usando a sintaxe `name: value`. Você pode fornecer o valor como um literal no RSX:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:attributes}}
|
||||
```
|
||||
|
||||
@@ -79,7 +79,7 @@ Os atributos também são especificados dentro dos colchetes `{}`, usando a sint
|
||||
|
||||
Dioxus tem um conjunto pré-configurado de atributos que você pode usar. O RSX é validado em tempo de compilação para garantir que você não especificou um atributo inválido. Se você quiser substituir esse comportamento por um nome de atributo personalizado, especifique o atributo entre aspas:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:custom_attributes}}
|
||||
```
|
||||
|
||||
@@ -91,7 +91,7 @@ Dioxus tem um conjunto pré-configurado de atributos que você pode usar. O RSX
|
||||
|
||||
Da mesma forma que você pode [formatar](https://doc.rust-lang.org/rust-by-example/hello/print/fmt.html) Rust _strings_, você também pode interpolar no texto RSX. Use `{variable}` para exibir o valor de uma variável em uma _string_, ou `{variable:?}` para usar a representação `Debug`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:formatting}}
|
||||
```
|
||||
|
||||
@@ -107,7 +107,7 @@ Da mesma forma que você pode [formatar](https://doc.rust-lang.org/rust-by-examp
|
||||
|
||||
Você pode incluir expressões Rust arbitrárias dentro do RSX, mas deve escapá-las entre colchetes `[]`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rsx_overview.rs:expression}}
|
||||
```
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Se você estiver trabalhando com itens pré-renderizados, modelos ou uma bibliot
|
||||
|
||||
Por exemplo, enviar um conversor de markdown para Dioxus pode aumentar significativamente o tamanho final do aplicativo. Em vez disso, você desejará pré-renderizar sua remarcação para HTML e, em seguida, incluir o HTML diretamente em sua saída. Usamos essa abordagem para a [página inicial do Dioxus](https://dioxuslabs.com):
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/dangerous_inner_html.rs:dangerous_inner_html}}
|
||||
```
|
||||
|
||||
@@ -22,7 +22,7 @@ A maioria dos atributos, quando renderizados, serão renderizados exatamente com
|
||||
|
||||
Portanto, este RSX não renderizaria o atributo `hidden`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/boolean_attribute.rs:boolean_attribute}}
|
||||
```
|
||||
|
||||
|
||||
@@ -35,6 +35,6 @@ cargo add dioxus-desktop
|
||||
|
||||
Edite seu `main.rs`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hello_world_desktop.rs:all}}
|
||||
```
|
||||
@@ -59,7 +59,7 @@ simple_logger = "*"
|
||||
|
||||
Edite seu `lib.rs`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -16,7 +16,7 @@ Ao trabalhar com frameworks web que requerem `Send`, é possível renderizar um
|
||||
|
||||
Se você quer apenas renderizar `rsx!` ou um VirtualDom para HTML, confira os documentos da API. É bem simples:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
// We can render VirtualDoms
|
||||
let mut vdom = VirtualDom::new(app);
|
||||
let _ = vdom.rebuild();
|
||||
@@ -61,7 +61,7 @@ tokio = { version = "1.15.0", features = ["full"] }
|
||||
|
||||
Agora, configure seu aplicativo Axum para responder em um _endpoint_.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
use axum::{response::Html, routing::get, Router};
|
||||
use dioxus::prelude::*;
|
||||
|
||||
@@ -83,7 +83,7 @@ async fn main() {
|
||||
|
||||
E, em seguida, adicione nosso _endpoint_. Podemos renderizar `rsx!` diretamente:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
async fn app_endpoint() -> Html<String> {
|
||||
Html(dioxus_ssr::render_lazy(rsx! {
|
||||
h1 { "hello world!" }
|
||||
@@ -93,7 +93,7 @@ async fn app_endpoint() -> Html<String> {
|
||||
|
||||
Ou podemos renderizar `VirtualDoms`.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
async fn app_endpoint() -> Html<String> {
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx!(h1 { "hello world" }))
|
||||
|
||||
@@ -23,7 +23,7 @@ cargo add dioxus-tui
|
||||
|
||||
Em seguida, edite seu `main.rs` com o modelo básico.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hello_world_tui.rs}}
|
||||
```
|
||||
|
||||
@@ -35,7 +35,7 @@ cargo run
|
||||
|
||||
Pressione "ctrl-c" para fechar o aplicativo. Para mudar de "ctrl-c" para apenas "q" para sair, você pode iniciar o aplicativo com uma configuração para desativar o sair padrão e usar a raiz TuiContext para sair por conta própria.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hello_world_tui_no_ctrl_c.rs}}
|
||||
```
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Adicione um `index.html` para o `Trunk` usar. Certifique-se de que seu elemento
|
||||
|
||||
Edite seu `main.rs`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hello_world_web.rs}}
|
||||
```
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Dioxus é uma estrutura portátil, de alto desempenho e ergonômica para a construção de interfaces de usuário multiplataforma no Rust. Este guia irá ajudá-lo a começar a escrever aplicativos Dioxus para a Web, Desktop, Mobile e muito mais.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
fn app(cx: Scope) -> Element {
|
||||
let mut count = use_state(cx, || 0);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Para evitar a repetição, você pode encapsular a lógica de negócios com base
|
||||
|
||||
Por exemplo, se muitos componentes precisam acessar uma _struct_ `AppSettings`, você pode criar um gancho de "atalho":
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_composed.rs:wrap_context}}
|
||||
```
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
Para renderizar diferentes elementos com base em uma condição, você pode usar uma instrução `if-else`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/conditional_rendering.rs:if_else}}
|
||||
```
|
||||
|
||||
@@ -16,7 +16,7 @@ Para renderizar diferentes elementos com base em uma condição, você pode usar
|
||||
|
||||
Como `Element` é uma `Option<VNode>`, os componentes que aceitam `Element` como _prop_ podem realmente inspecionar seu conteúdo e renderizar coisas diferentes com base nisso. Exemplo:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/component_children_inspect.rs:Clickable}}
|
||||
```
|
||||
|
||||
@@ -26,7 +26,7 @@ Você não pode modificar o `Element`, mas se precisar de uma versão modificada
|
||||
|
||||
Para renderizar nada, você pode retornar `None` de um componente. Isso é útil se você deseja ocultar algo condicionalmente:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/conditional_rendering.rs:conditional_none}}
|
||||
```
|
||||
|
||||
@@ -47,7 +47,7 @@ Para isso, o Dioxus aceita iteradores que produzem `Element`s. Então precisamos
|
||||
|
||||
Exemplo: suponha que você tenha uma lista de comentários que deseja renderizar. Então, você pode renderizá-los assim:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/rendering_lists.rs:render_list}}
|
||||
```
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Os manipuladores de eventos são semelhantes aos atributos regulares, mas seus n
|
||||
|
||||
Por exemplo, para manipular cliques em um elemento, podemos especificar um manipulador `onclick`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/event_click.rs:rsx}}
|
||||
```
|
||||
|
||||
@@ -29,7 +29,7 @@ Para saber o que os diferentes tipos de eventos fornecem, leia os [documentos do
|
||||
|
||||
Quando você tem, por exemplo um `button` dentro de um `div`, qualquer clique no `button` também é um clique no `div`. Por esta razão, Dioxus propaga o evento click: primeiro, ele é acionado no elemento alvo, depois nos elementos pai. Se você quiser evitar esse comportamento, você pode chamar `cancel_bubble()` no evento:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/event_click.rs:rsx}}
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ Alguns eventos têm um comportamento padrão. Para eventos de teclado, isso pode
|
||||
|
||||
Em alguns casos, você pode querer evitar esse comportamento padrão. Para isso, você pode adicionar o atributo `prevent_default` com o nome do manipulador cujo comportamento padrão você deseja interromper. Este atributo é especial: você pode anexá-lo várias vezes para vários atributos:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/event_prevent_default.rs:prevent_default}}
|
||||
```
|
||||
|
||||
@@ -51,13 +51,13 @@ Quaisquer manipuladores de eventos ainda serão chamados.
|
||||
|
||||
Às vezes, você pode querer criar um componente que aceite um manipulador de eventos. Um exemplo simples seria um componente `FancyButton`, que aceita um manipulador `on_click`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/event_handler_prop.rs:component_with_handler}}
|
||||
```
|
||||
|
||||
Então, você pode usá-lo como qualquer outro manipulador:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/event_handler_prop.rs:usage}}
|
||||
```
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Para lógica com estado, você pode usar _hooks_. _Hooks_ são funções Rust qu
|
||||
|
||||
Por exemplo, você pode ter visto o exemplo do contador, no qual o estado (um número) é rastreado usando o _hook_ `use_state`:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_counter.rs:component}}
|
||||
```
|
||||
|
||||
@@ -26,7 +26,7 @@ Toda vez que o estado do componente muda, ele é renderizado novamente e a funç
|
||||
|
||||
Você pode usar vários _hooks_ no mesmo componente se quiser:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_counter_two_state.rs:component}}
|
||||
```
|
||||
|
||||
@@ -38,7 +38,7 @@ O exemplo acima pode parecer um pouco mágico, já que as funções Rust normalm
|
||||
|
||||
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?
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_counter_two_state.rs:use_state_calls}}
|
||||
```
|
||||
|
||||
@@ -54,19 +54,19 @@ Essas regras significam que há certas coisas que você não pode fazer com _hoo
|
||||
|
||||
### Sem Hooks em Condicionais
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_bad.rs:conditional}}
|
||||
```
|
||||
|
||||
### Sem Hooks em Closures
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_bad.rs:closure}}
|
||||
```
|
||||
|
||||
### Sem Hooks em Loops
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_bad.rs:loop}}
|
||||
```
|
||||
|
||||
@@ -80,7 +80,7 @@ Felizmente, existe outro _hook_ para isso, `use_ref`! É semelhante ao `use_stat
|
||||
|
||||
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:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/hooks_use_ref.rs:component}}
|
||||
```
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ dioxus-router = { version = "*" }
|
||||
|
||||
Ao contrário de outros roteadores no ecossistema Rust, nosso roteador é construído de forma declarativa. Isso torna possível compor o layout do nosso aplicativo simplesmente organizando os componentes.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
rsx!{
|
||||
Router {
|
||||
Route { to: "/home", Home {} }
|
||||
@@ -41,7 +41,7 @@ Podemos corrigir isso de duas maneiras:
|
||||
|
||||
- Uma página 404 de _fallback_
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
rsx!{
|
||||
Router {
|
||||
Route { to: "/home", Home {} }
|
||||
@@ -53,7 +53,7 @@ rsx!{
|
||||
|
||||
- Redirecionar 404 para _Home_
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
rsx!{
|
||||
Router {
|
||||
Route { to: "/home", Home {} }
|
||||
@@ -67,7 +67,7 @@ rsx!{
|
||||
|
||||
Para que nosso aplicativo navegue nessas rotas, podemos fornecer elementos clicáveis chamados Links. Eles simplesmente envolvem elementos `<a>` que, quando clicados, navegam no aplicativo para o local determinado.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
rsx!{
|
||||
Link {
|
||||
to: "/home",
|
||||
|
||||
@@ -12,7 +12,7 @@ Por exemplo, suponha que queremos construir um editor de memes. Queremos ter uma
|
||||
|
||||
Começamos com um componente `Meme`, responsável por renderizar um meme com uma determinada legenda:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor.rs:meme_component}}
|
||||
```
|
||||
|
||||
@@ -20,13 +20,13 @@ Começamos com um componente `Meme`, responsável por renderizar um meme com uma
|
||||
|
||||
Também criamos um editor de legendas, totalmente desacoplado do meme. O editor de legendas não deve armazenar a legenda em si – caso contrário, como iremos fornecê-la ao componente `Meme`? Em vez disso, ele deve aceitar a legenda atual como um suporte, bem como um manipulador de eventos para delegar eventos de entrada para:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor.rs:caption_editor}}
|
||||
```
|
||||
|
||||
Finalmente, um terceiro componente renderizará os outros dois como filhos. Ele será responsável por manter o estado e passar os _props_ relevantes.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor.rs:meme_editor}}
|
||||
```
|
||||
|
||||
@@ -46,19 +46,19 @@ A Dioxus oferece uma solução melhor do que esta "perfuração com hélice" –
|
||||
|
||||
Primeiro, temos que criar um _struct_ para nossa configuração de modo escuro:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor_dark_mode.rs:DarkMode_struct}}
|
||||
```
|
||||
|
||||
Agora, em um componente de nível superior (como `App`), podemos fornecer o contexto `DarkMode` para todos os componentes filhos:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor_dark_mode.rs:context_provider}}
|
||||
```
|
||||
|
||||
Como resultado, qualquer componente filho de `App` (direto ou não), pode acessar o contexto `DarkMode`.
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor_dark_mode.rs:use_context}}
|
||||
```
|
||||
|
||||
@@ -66,6 +66,6 @@ Como resultado, qualquer componente filho de `App` (direto ou não), pode acessa
|
||||
|
||||
Por exemplo, aqui está como implementaríamos a alternância do modo escuro, que lê o contexto (para determinar a cor que deve renderizar) e grava nele (para alternar o modo escuro):
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/meme_editor_dark_mode.rs:toggle}}
|
||||
```
|
||||
@@ -6,7 +6,7 @@ As interfaces geralmente precisam fornecer uma maneira de inserir dados: por exe
|
||||
|
||||
Com entradas controladas, você fica diretamente responsável pelo estado da entrada. Isso lhe dá muita flexibilidade e facilita manter as coisas em sincronia. Por exemplo, é assim que você criaria uma entrada de texto controlada:
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/input_controlled.rs:component}}
|
||||
```
|
||||
|
||||
@@ -24,7 +24,7 @@ Como alternativa às entradas controladas, você pode simplesmente deixar a plat
|
||||
|
||||
Como você não tem necessariamente o valor atual da entrada não controlada no estado, você pode acessá-lo ouvindo os eventos `oninput` (de maneira semelhante aos componentes controlados) ou, se a entrada for parte de um formulário, você pode acessar os dados do formulário nos eventos do formulário (por exemplo, `oninput` ou `onsubmit`):
|
||||
|
||||
```rust
|
||||
```rust, no_run
|
||||
{{#include ../../../examples/input_uncontrolled.rs:component}}
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user