Forráskód Böngészése

wip: update readme

Jonathan Kelley 3 éve
szülő
commit
9bd56ee
4 módosított fájl, 149 hozzáadás és 23 törlés
  1. 143 0
      README.md
  2. 1 3
      packages/core/src/diff.rs
  3. 0 10
      packages/core/src/nodes.rs
  4. 5 10
      packages/core/src/virtual_dom.rs

+ 143 - 0
README.md

@@ -199,6 +199,149 @@ You shouldn't use Dioxus if:
 - You want to support browsers where Wasm or asm.js are not supported.
 
 
+## Show me some examples!
+
+In our collection of examples, guides, and tutorials, we have:
+- The book (an introductory course)
+- The guide (an in-depth analysis of everything in Dioxus)
+- The reference (a collection of examples with heavy documentation)
+- The general examples
+- The platform-specific examples (web, ssr, desktop, mobile, server)
+  
+Here's what a few common tasks look like in Dioxus:
+
+Nested components with children and internal state:
+```rust
+fn App(cx: Context, props: &()) -> Element {
+  cx.render(rsx!( Toggle { "Toggle me" } ))
+}
+
+#[derive(PartialEq, Props)]
+struct ToggleProps { children: Element }
+
+fn Toggle(cx: Context, props: &ToggleProps) -> Element {
+  let mut toggled = use_state(cx, || false);
+  cx.render(rsx!{
+    div {
+      {&props.children}
+      button { onclick: move |_| toggled.set(true),
+        {toggled.and_then(|| "On").or_else(|| "Off")}
+      }
+    }
+  })
+}
+```
+
+Controlled inputs:
+```rust
+fn App(cx: Context, props: &()) -> Element {
+  let value = use_state(cx, String::new);
+  cx.render(rsx!( 
+    input {
+      "type": "text",
+      value: "{value}",
+      oninput: move |evt| value.set(evt.value.clone())
+    }
+  ))
+}
+```
+
+Lists and Conditional rendering:
+```rust
+fn App(cx: Context, props: &()) -> Element {
+  let list = (0..10).map(|i| {
+    rsx!(li { key: "{i}", "Value: {i}" })
+  });
+  
+  let title = match list.len() {
+    0 => rsx!("Not enough"),
+    _ => rsx!("Plenty!"),
+  };
+
+  if should_show {
+    cx.render(rsx!( 
+      {title}
+      ul { {list} } 
+    ))
+  } else {
+    None
+  }
+}
+```
+
+Tiny components:
+```rust
+static App: FC<()> = |cx, _| rsx!(cx, div {"hello world!"});
+```
+
+Borrowed prop contents:
+```rust
+fn App(cx: Context, props: &()) -> Element {
+  let name = use_state(cx, || String::from("example"));
+  rsx!(cx, Child { title: name.as_str() })
+}
+
+#[derive(Props)]
+struct ChildProps<'a> { title: &'a str }
+
+fn Child(cx: Context, props: &ChildProps) -> Element {
+  rsx!(cx, "Hello {props.title}")
+}
+```
+
+Global State
+```rust
+struct GlobalState { name: String }
+
+fn App(cx: Context, props: &()) -> Element {
+  use_provide_shared_state(cx, || GlobalState { name: String::from("Toby") })
+  rsx!(cx, Leaf {})
+}
+
+fn Leaf(cx: Context, props: &()) -> Element {
+  let state = use_consume_shared_state::<GlobalState>(cx)?;
+  rsx!(cx, "Hello {state.name}")
+}
+```
+
+Router (inspired by Yew-Router)
+```rust
+#[derive(PartialEq, Clone,  Hash, Eq, Routable)]
+enum Route {
+  #[at("/")]
+  Home,
+  #[at("/post/{id}")]
+  Post(id)
+}
+
+fn App(cx: Context, props: &()) -> Element {
+  let route = use_router(cx, Route::parse);
+  cx.render(rsx!(div {
+    {match route {
+      Route::Home => rsx!( Home {} ),
+      Route::Post(id) => rsx!( Post { id: id })
+    }}
+  }))  
+}
+```
+
+Suspense 
+```rust
+fn App(cx: Context, props: &()) -> Element {
+  let doggo = use_suspense(cx,
+    || async { reqwest::get("https://dog.ceo/api/breeds/image/random").await.unwrap().json::<Response>().await.unwrap() },
+    |response| cx.render(rsx!( img { src: "{response.message}" }))
+  );
+  
+  cx.render(rsx!{
+    div {
+      "One doggo coming right up:"
+      {doggo}
+    }
+  })
+}
+```
+
 ## License
 
 This project is licensed under the [MIT license].

+ 1 - 3
packages/core/src/diff.rs

@@ -365,7 +365,6 @@ impl<'bump> DiffState<'bump> {
 
     fn create_text_node(&mut self, vtext: &'bump VText<'bump>, node: &'bump VNode<'bump>) {
         let real_id = self.scopes.reserve_node(node);
-        let parent = self.stack.element_stack.last().unwrap();
 
         self.mutations.create_text_node(vtext.text, real_id);
         vtext.dom_id.set(Some(real_id));
@@ -413,7 +412,6 @@ impl<'bump> DiffState<'bump> {
         let real_id = self.scopes.reserve_node(node);
         self.stack.element_stack.push(real_id);
         dom_id.set(Some(real_id));
-        log::debug!("Parent ID for {:?} set to {:?}", real_id, parent_id.get());
 
         self.mutations.create_element(tag_name, *namespace, real_id);
 
@@ -545,7 +543,7 @@ impl<'bump> DiffState<'bump> {
         &mut self,
         old: &'bump VText<'bump>,
         new: &'bump VText<'bump>,
-        old_node: &'bump VNode<'bump>,
+        _old_node: &'bump VNode<'bump>,
         new_node: &'bump VNode<'bump>,
     ) {
         if let Some(root) = old.dom_id.get() {

+ 0 - 10
packages/core/src/nodes.rs

@@ -261,9 +261,7 @@ pub struct VAnchor {
 /// A bump-allocated string slice and metadata.
 pub struct VText<'src> {
     pub text: &'src str,
-
     pub dom_id: Cell<Option<ElementId>>,
-
     pub is_static: bool,
 }
 
@@ -276,20 +274,12 @@ pub struct VFragment<'src> {
 /// An element like a "div" with children, listeners, and attributes.
 pub struct VElement<'a> {
     pub tag_name: &'static str,
-
     pub namespace: Option<&'static str>,
-
     pub key: Option<&'a str>,
-
     pub dom_id: Cell<Option<ElementId>>,
-
-    // Keep the parent id around so we can bubble events through the tree
     pub parent_id: Cell<Option<ElementId>>,
-
     pub listeners: &'a [Listener<'a>],
-
     pub attributes: &'a [Attribute<'a>],
-
     pub children: &'a [VNode<'a>],
 }
 

+ 5 - 10
packages/core/src/virtual_dom.rs

@@ -9,7 +9,6 @@ use fxhash::FxHashSet;
 use indexmap::IndexSet;
 use smallvec::SmallVec;
 use std::pin::Pin;
-use std::rc::Rc;
 use std::sync::Arc;
 use std::task::Poll;
 use std::{any::Any, collections::VecDeque};
@@ -293,6 +292,7 @@ impl VirtualDom {
 
                         let mut items = scope.items.borrow_mut();
 
+                        // really this should just be retain_mut but that doesn't exist yet
                         while let Some(mut task) = items.tasks.pop() {
                             // todo: does this make sense?
                             // I don't usually write futures by hand
@@ -312,9 +312,7 @@ impl VirtualDom {
                             scopes_to_clear.push(*fut);
                         }
 
-                        for task in unfinished_tasks.drain(..) {
-                            items.tasks.push(task);
-                        }
+                        items.tasks.extend(unfinished_tasks.drain(..));
                     }
 
                     for scope in scopes_to_clear {
@@ -461,17 +459,14 @@ impl VirtualDom {
                         );
                         diff_state.stack.push(DiffInstruction::Diff { new, old });
                         diff_state.stack.scope_stack.push(scopeid);
+
                         let scope = scopes.get_scope(&scopeid).unwrap();
-                        let container = scope.container;
-                        log::debug!("scope {:?} container {:?}", scope.our_arena_idx, container);
-                        diff_state.stack.element_stack.push(container);
+                        diff_state.stack.element_stack.push(scope.container);
                     }
                 }
             }
 
-            let work_completed = diff_state.work(&mut deadline);
-
-            if work_completed {
+            if diff_state.work(&mut deadline) {
                 let DiffState {
                     mutations,
                     seen_scopes,