Bladeren bron

Add a better introduction to what Components are.

Reinis Mazeiks 3 jaren geleden
bovenliggende
commit
f5907a682e

BIN
docs/guide/src/components/component_example_title.png


BIN
docs/guide/src/components/component_example_votes.png


+ 3 - 25
docs/guide/src/components/index.md

@@ -12,32 +12,10 @@ In short, a component is a special function that takes input properties and outp
 
 ### Real-world example
 
-Take a look at a post on Reddit:
+Let's use a Reddit post as an example:
 
 ![Reddit Post](../images/reddit_post.png)
 
-We can build this post as a component, consisting of multiple subcomponents. It has several inputs:
-
-- The score
-- The number of comments
-- How long ago it was posted
-- The url short address
-- The title
-- The username of the original poster
-
-If we wanted to sketch out these requirements in Rust, we would start with a struct:
-
-```rust
-struct PostData {
-    score: i32,
-    comment_count: u32,
-    post_time: Instant,
-    url: String,
-    title: String,
-    original_poster_name: String
-}
-```
-
 If we look at the layout of the component, we notice quite a few buttons and pieces of functionality:
 
 - Upvote/Downvote
@@ -52,7 +30,7 @@ If we look at the layout of the component, we notice quite a few buttons and pie
 - View article
 - Visit user
 
-If we included all this functionality in one `rsx!` call it would be huge! Instead, let's break the post down into some core pieces:
+If we included all this functionality in one `rsx!` call it would be huge! Instead, let's break the post down into Components:
 
 ![Post as Component](../images/reddit_post_components.png)
 
@@ -61,4 +39,4 @@ If we included all this functionality in one `rsx!` call it would be huge! Inste
 - **MetaCard**: Original Poster, Time Submitted
 - **ActionCard**: View comments, Share, Save, Hide, Give award, Report, Crosspost
 
-In this chapter, we'll learn how to define our own components.
+In this chapter, we'll learn how to define these components.

+ 47 - 8
docs/guide/src/components/propsmacro.md

@@ -7,7 +7,7 @@ Dioxus components are functions that accept Props as input and output an Element
 - The inline_props macro    
 
 ## Props
-All properties that your components take must implement the `Props` trait. We can derive this trait on our own structs to define a Component's 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.
 
@@ -20,16 +20,41 @@ There are 2 flavors of Props: owned and borrowed.
 
 Owned Props are very simple – they don't borrow anything. Example:
 ```rust
-#[derive(Props, PartialEq)]
-struct MyProps {
-    name: String
+// Remember: owned props must implement PartialEq!
+#[derive(PartialEq, Props)]
+struct VoteButtonProps {
+    score: i32
 }
 
-fn Demo(cx: Scope<MyProps>) -> Element {
-    todo!()
+fn VoteButton(cx: Scope<VoteButtonProps>) -> Element {
+    cx.render(rsx!{
+        div {
+            div { "+" }
+            div { "{cx.props.score}"}
+            div { "-" }
+        }
+    })
+}
+```
+
+Now, we can use the VoteButton Component like we would use a regular HTML element:
+
+```rust
+fn main() {
+    dioxus::desktop::launch(App);
+}
+
+fn App(cx: Scope) -> Element {
+    cx.render(rsx! (
+        VoteButton { score: 42 }
+    ))
 }
 ```
 
+And we can see that the Component indeed gets rendered:
+
+![Screenshot of running app. Text: "+ \ 42 \ -"](component_example_votes.png)
+
 > The simplest Owned Props you can have is `()` - or no value at all. This is what the `App` Component takes as props. `Scope` accepts a generic for the Props which defaults to `()`.
 > 
 > ```rust
@@ -42,7 +67,7 @@ fn Demo(cx: Scope<MyProps>) -> Element {
 
 ### Borrowed Props
 
-Owning a string works well as long as you only need it in one place. But what if we need to pass a String from a `Post` Component to a `TitleCard` subcomponent? A naive solution might be to [`.clone()`](https://doc.rust-lang.org/std/clone/trait.Clone.html) the String, creating a copy of it – but this would be inefficient, especially for larger Strings.
+Owning props works well if your props are easy to copy around - like a single number. But what if we need to pass a larger data type, like a String from an `App` Component to a `TitleCard` subcomponent? A naive solution might be to [`.clone()`](https://doc.rust-lang.org/std/clone/trait.Clone.html) the String, creating a copy of it for the subcomponent – but this would be inefficient, especially for larger Strings.
 
 Rust allows for something more efficient – borrowing the String as a `&str`. Instead of creating a copy, this will give us a reference to the original String – this is what Borrowed Props are for!
 
@@ -61,7 +86,21 @@ fn TitleCard<'a>(cx: Scope<'a, TitleCardProps<'a>>) -> Element {
 }
 ```
 
-This lifetime `'a` tells the compiler that as long as `title` exists, the String it was created from must also exist. Dioxus will happily accept such a component.
+This lifetime `'a` tells the compiler that as long as `title` exists, the String it was created from must also exist. Dioxus will happily accept such a component – we can now render it alongside our VoteButton!
+
+```rust
+fn App(cx: Scope) -> Element {
+    // For the sake of an example, we create the &str here.
+    // But you might as well borrow it from an owned String type.
+    let hello = "Hello Dioxus!";
+
+    cx.render(rsx! (
+        VoteButton { score: 42 },
+        TitleCard { title: hello }
+    ))
+}
+```
+![New screenshot of running app, now including a "Hello Dioxus!" heading.](component_example_title.png)
 
 ## Memoization