Make minor grammar, spelling, and style changes

This commit is contained in:
Kris Warner committed 2022-03-27 21:24:14 -04:00
1 parent cb1e16c91c
commit e61fa44497
10 files changed
+27 -28

No files matched your search

@@ -1,6 +1,6 @@
# Passing children and attributes # Passing children and attributes
Often times, you'll want to wrap some important functionality *around* your state, not directly nested *inside* another component. In these cases, you'll want to pass elements and attributes into a component and let the component place them appropriately. Oftentimes, you'll want to wrap some important functionality *around* your state, not directly nested *inside* another component. In these cases, you'll want to pass elements and attributes into a component and let the component place them appropriately.
In this chapter, you'll learn about: In this chapter, you'll learn about:
- Passing elements into components - Passing elements into components
@@ -216,4 +216,3 @@ In this chapter, we learned:
- How the `attributes` field works on component properties - How the `attributes` field works on component properties
- How to convert `listeners` into `EventHandlers` for components - How to convert `listeners` into `EventHandlers` for components
- How to extend any node with custom attributes and children - How to extend any node with custom attributes and children
+11 -9
View File
@@ -1,4 +1,5 @@
# Component Properties # Component Properties
Dioxus components are functions that accept Props as input and output an Element. In fact, the `App` function you saw in the previous chapter was a component with no Props! Most components, however, will need to take some Props to render something useful – so, in this section, we'll learn about props: Dioxus components are functions that accept Props as input and output an Element. In fact, the `App` function you saw in the previous chapter was a component with no Props! Most components, however, will need to take some Props to render something useful – so, in this section, we'll learn about props:
- Deriving the Props trait - Deriving the Props trait
@@ -7,6 +8,7 @@ Dioxus components are functions that accept Props as input and output an Element
- The inline_props macro - The inline_props macro
## Props ## Props
The input of your Component must be passed in a single struct, which must implement the `Props` trait. We can derive this trait automatically with `#[derive(Props)]`. The input of your Component must be passed in a single struct, which must implement the `Props` trait. We can derive this trait automatically with `#[derive(Props)]`.
> Dioxus `Props` is very similar to [@idanarye](https://github.com/idanarye)'s [TypedBuilder crate](https://github.com/idanarye/rust-typed-builder) and supports many of the same parameters. > Dioxus `Props` is very similar to [@idanarye](https://github.com/idanarye)'s [TypedBuilder crate](https://github.com/idanarye/rust-typed-builder) and supports many of the same parameters.
@@ -152,7 +154,7 @@ fn Demo(cx: MyProps) -> Element {
}) })
} }
``` ```
In this example ˋnameˋ is a required prop and ˋdescriptionˋ is optional. In this example `name` is a required prop and `description` is optional.
This means we can completely omit the description field when calling the component: This means we can completely omit the description field when calling the component:
```rust ```rust
@@ -163,20 +165,20 @@ rsx!{
} }
} }
``` ```
Additionally if we provide a value we don't have to wrap it with ˋSome(…)ˋ. This is done automatically for us: Additionally if we provide a value we don't have to wrap it with `Some(…)`. This is done automatically for us:
ˋˋˋrust ```rust
rsx!{ rsx!{
Demo { Demo {
name: "Thing".to_string(), name: "Thing".to_string(),
description: "This is explains it".to_string(), description: "This is explains it".to_string(),
} }
} }
ˋˋˋ ```
If you want to make a prop required even though it is of type ˋOptionˋ you can provide the ˋ!optionalˋ modifier: If you want to make a prop required even though it is of type `Option` you can provide the `!optional` modifier:
ˋˋˋrust ```rust
#[derive(Props, PartialEq)] #[derive(Props, PartialEq)]
struct MyProps { struct MyProps {
name: String, name: String,
@@ -184,11 +186,11 @@ struct MyProps {
#[props(!optional)] #[props(!optional)]
description: Option<String> description: Option<String>
} }
ˋˋˋ ```
This can be especially useful if you have a type alias named ˋOptionˋ in the current scope. This can be especially useful if you have a type alias named `Option` in the current scope.
For more information on how tags work, check out the [TypedBuilder](https://github.com/idanarye/rust-typed-builder) crate. However, all attributes for props in Dioxus are flattened (no need for `setter` syntax) and the `optional` field is new. The `optional` modifier is a combination of two separate modifiers: `default` and `strip_option` and it is automatically detected on ˋOption<…>ˋ types. For more information on how tags work, check out the [TypedBuilder](https://github.com/idanarye/rust-typed-builder) crate. However, all attributes for props in Dioxus are flattened (no need for `setter` syntax) and the `optional` field is new. The `optional` modifier is a combination of two separate modifiers: `default` and `strip_option` and it is automatically detected on `Option<…>` types.
The full list of Dioxus' modifiers includes: The full list of Dioxus' modifiers includes:
@@ -1,6 +1,6 @@
# Conditional Rendering # Conditional Rendering
Your components will often need to display different things depending on different conditions. With Dioxus, we can use Rust's normal control flow to conditional hide, show, and modify the structure of our markup. Your components will often need to display different things depending on different conditions. With Dioxus, we can use Rust's normal control flow to conditionally hide, show, and modify the structure of our markup.
In this chapter, you'll learn: In this chapter, you'll learn:
- How to return different Elements depending on a condition - How to return different Elements depending on a condition
@@ -7,7 +7,6 @@ In this section, we'll cover special attributes built into Dioxus:
- `dangerous_inner_html` - `dangerous_inner_html`
- Boolean attributes - Boolean attributes
- `prevent_default` - `prevent_default`
<!-- - `..Attributes` -->
- event handlers as string attributes - event handlers as string attributes
- `value`, `checked`, and `selected` - `value`, `checked`, and `selected`
+3 -1
View File
@@ -8,6 +8,7 @@ In this chapter, we'll cover:
- Element properties - Element properties
## Declaring our first Element ## Declaring our first Element
Because Dioxus is mostly used with HTML/CSS renderers, the default Element "collection" is HTML. Provided the `html` feature is not disabled, we can declare Elements using the `rsx!` macro: Because Dioxus is mostly used with HTML/CSS renderers, the default Element "collection" is HTML. Provided the `html` feature is not disabled, we can declare Elements using the `rsx!` macro:
```rust ```rust
@@ -29,6 +30,7 @@ Produces:
``` ```
We can construct any valid HTML tag with the `tag {}` pattern and expect the resulting HTML structure to resemble our declaration. We can construct any valid HTML tag with the `tag {}` pattern and expect the resulting HTML structure to resemble our declaration.
## Composing Elements ## Composing Elements
Of course, we need more complex structures to make our apps actually useful! Just like HTML, the `rsx!` macro lets us nest Elements inside of each other. Of course, we need more complex structures to make our apps actually useful! Just like HTML, the `rsx!` macro lets us nest Elements inside of each other.
@@ -150,7 +152,7 @@ All element attributes must occur *before* child elements. The `rsx!` macro will
Listeners are a special type of Attribute that only accept functions. Listeners let us attach functionality to our Elements by running a provided closure whenever the specified Listener is triggered. Listeners are a special type of Attribute that only accept functions. Listeners let us attach functionality to our Elements by running a provided closure whenever the specified Listener is triggered.
We'll cover listeners in more depth in the Adding Interactivity chapter, but for now, just know that every listener must start with the `on` keyword and accepts closures. We'll cover listeners in more depth in the Adding Interactivity chapter, but for now, just know that every listener starts with "on" and accepts closures.
```rust ```rust
rsx!( rsx!(
+2 -2
View File
@@ -115,13 +115,13 @@ At this point, you could call `cargo run` and be greeted with a simple `Hello, W
### Dissecting our example ### Dissecting our example
The `use` statement at the top of our app imports everything from the the `prelude` module. `use`-ing the prelude imports the right traits, types, and macros needed for working with Dioxus. The `use` statement at the top of our app imports everything from the `prelude` module. `use`-ing the prelude imports the right traits, types, and macros needed for working with Dioxus.
```rust ```rust
use dioxus::prelude::*; use dioxus::prelude::*;
``` ```
This initialization code launches a Tokio runtime on a helper thread where your code will run. Then, the WebView renderer will be launched on the main-thread. Due to platform requirements, the main thread is blocked by your app's event loop. This initialization code launches a Tokio runtime on a helper thread where your code will run. Then, the WebView renderer will be launched on the main thread. Due to platform requirements, the main thread is blocked by your app's event loop.
```rust ```rust
fn main() { fn main() {
@@ -1,6 +1,6 @@
# Event handlers # Event handlers
To make our boring UIs less static and more interesting, we want to add the ability to interact to user input. To do this, we need to add some event handlers. To make our boring UIs less static and more interesting, we want to add the ability to interact with user input. To do this, we need to add some event handlers.
## The most basic events: clicks ## The most basic events: clicks
@@ -82,7 +82,7 @@ div {
} }
``` ```
In this particular layout, a click on the inner div is transitively also a click on the outer div. If we didn't want the outer div to be triggered every time we trigger the inner div, then we'd want to call "cancel_bubble". In this particular layout, a click on the inner div is transitively also a click on the outer div. If we didn't want the outer div to be triggered every time we trigger the inner div, then we'd want to call `cancel_bubble()`.
This will prevent any listeners above the current listener from being triggered. This will prevent any listeners above the current listener from being triggered.
@@ -102,7 +102,7 @@ div {
## Prevent Default ## Prevent Default
With HTML based renderers, the browser will automatically perform some action. For text inputs, this would be entering the provided key. For forms, this might involve navigating the page. With HTML-based renderers, the browser will automatically perform some action. For text inputs, this would be entering the provided key. For forms, this might involve navigating the page.
In some instances, you don't want this default behavior. In these cases, instead of handling the event directly, you'd want to prevent any default handlers. In some instances, you don't want this default behavior. In these cases, instead of handling the event directly, you'd want to prevent any default handlers.
+3 -5
View File
@@ -60,14 +60,13 @@ cx.render(rsx!{
## Uncontrolled Inputs ## Uncontrolled Inputs
When working with large sets of inputs, you might be quickly tired of creating `use_state` for each value. Additionally, the pattern of one use_state per interaction might deteriorate when you need to have a flexible number of inputs. In these cases, we use "uncontrolled" inputs. Here, we don't drive the value of the input from the use_state, choosing to leave it in an "uncontrolled" state. When working with large sets of inputs, you might be quickly tired of creating `use_state` for each value. Additionally, the pattern of one `use_state` per interaction might deteriorate when you need to have a flexible number of inputs. In these cases, we use "uncontrolled" inputs. Here, we don't drive the value of the input from the `use_state`, choosing to leave it in an "uncontrolled" state.
This approach can be more performant, more flexible, but more prone to UI inconsistencies than its controlled counterpart. This approach can be more performant and more flexible, but more prone to UI inconsistencies than its controlled counterpart.
To use the "uncontrolled" pattern, we simply omit setting the value of the input. Instead, we can react to the change directly on the input itself, or from a form element higher up in the tree. To use the "uncontrolled" pattern, we simply omit setting the value of the input. Instead, we can react to the change directly on the input itself, or from a form element higher up in the tree.
For this example, we don't attach any `use_state` handles into the labels. Instead, we simply attach an `oninput` handler to the form element. This will run each time any of the child inputs change, allowing us to perform tasks like form validation.
For this example, we don't attach any `use_state` handles into the labels. Instead, we simply attach an "oninput" handler to the form element. This will run each time any of the child inputs change, allowing us to perform tasks like form validation.
```rust ```rust
form { form {
@@ -81,4 +80,3 @@ form {
input { name: "date", } input { name: "date", }
} }
``` ```
+1 -1
View File
@@ -3,7 +3,7 @@
The first fundamental hook for state management is `use_state`. This particular hook is designed to work well with the entire Dioxus ecosystem including futures, children, and memoization. The first fundamental hook for state management is `use_state`. This particular hook is designed to work well with the entire Dioxus ecosystem including futures, children, and memoization.
## Basic usage. ## Basic usage
The simplest use case of `use_state` is a simple counter. The handle returned by `use_state` implements `Add` and `AddAssign`. Writing through `AddAssign` will automatically mark the component as dirty, forcing an update. The simplest use case of `use_state` is a simple counter. The handle returned by `use_state` implements `Add` and `AddAssign`. Writing through `AddAssign` will automatically mark the component as dirty, forcing an update.
+2 -3
View File
@@ -1,6 +1,6 @@
# Managing State # Managing State
Every app you'll build with Dioxus will have some sort of state that needs to be maintained and updated as your users interact with it. However, managing state can be particular challenging at times, and is frequently the source of bugs in many GUI frameworks. Every app you'll build with Dioxus will have some sort of state that needs to be maintained and updated as your users interact with it. However, managing state can be particularly challenging at times, and is frequently the source of bugs in many GUI frameworks.
In this chapter, we'll cover the various ways to manage state, the appropriate terminology, various patterns, and some problems you might run into. In this chapter, we'll cover the various ways to manage state, the appropriate terminology, various patterns, and some problems you might run into.
@@ -11,7 +11,7 @@ Why do people say state management is so difficult? What does it mean?
Generally, state management is the code you need to write to ensure that your app renders the *correct* content. If the user inputs a name, then you need to display the appropriate response - like alerts, validation, and disable/enable various elements on the page. Things can quickly become tricky if you need loading screens and cancellable tasks. Generally, state management is the code you need to write to ensure that your app renders the *correct* content. If the user inputs a name, then you need to display the appropriate response - like alerts, validation, and disable/enable various elements on the page. Things can quickly become tricky if you need loading screens and cancellable tasks.
For the simplest of apps, all your state can enter the app from the root props. This is common in server-side rendering - we can collect all of the required state *before* rendering the content. For the simplest of apps, all of your state can enter the app from the root props. This is common in server-side rendering - we can collect all of the required state *before* rendering the content.
```rust ```rust
let all_content = get_all_content().await; let all_content = get_all_content().await;
@@ -36,4 +36,3 @@ To deal with complexity, you have a couple of options:
- Lift state upwards to be spread across multiple components (fan out). - Lift state upwards to be spread across multiple components (fan out).
- Use the Context API to share state globally. - Use the Context API to share state globally.
- Use a dedicated state management solution like Fermi. - Use a dedicated state management solution like Fermi.