wip: update readme

This commit is contained in:
Jonathan Kelley 2021-11-12 16:06:33 -05:00
parent 55e6dd9701
commit 9bd56ee499
4 changed files with 149 additions and 23 deletions

143
README.md
View file

@ -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].

View file

@ -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() {

View file

@ -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>],
}

View file

@ -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,