docs: examples
This commit is contained in:
1 parent
818043e5e4
commit
d9e6d0925b
33 files changed
+732
-152
No files matched your search
+46
-25
@@ -1,29 +1,50 @@
|
||||
# Examples
|
||||
|
||||
Most of these examples are run through webview so you don't need the dioxus cli installed to preview the functionality. Anything labeled `_web` will need to be built with the Dioxus CLI to preview features that only a native bundle can handle.
|
||||
Most of these examples are run through webview so you don't need the dioxus cli installed to preview the functionality.
|
||||
|
||||
List of examples:
|
||||
These examples are fully-fledged micro apps. They can be ran with the `cargo run --example XYZ`
|
||||
|
||||
| Example | What it does |
|
||||
| --------------------------------------- | ------------ |
|
||||
| [The basics](./basics.rs) | this does |
|
||||
| [fine grained reactivity](./signals.rs) | this does |
|
||||
| Global State Management | this does |
|
||||
| Virtual Refs | this does |
|
||||
| Inline Styles | this does |
|
||||
| Conditional Rendering | this does |
|
||||
| Maps/Iterators | this does |
|
||||
| Render To string | this does |
|
||||
| Component Children | this does |
|
||||
| Function Driven children | this does |
|
||||
| Memoization | this does |
|
||||
| Borrowed Data | this does |
|
||||
| Fragments | this does |
|
||||
| Null/None Components | this does |
|
||||
| Spread Pattern for props | this does |
|
||||
| Controlled Inputs | this does |
|
||||
| Custom Elements | this does |
|
||||
| Testing And debugging | this does |
|
||||
| Asynchronous Data | this does |
|
||||
| Fiber/Scheduled Rendering | this does |
|
||||
| CSS Compiled Styles | this does |
|
||||
| Example | What it does | Status |
|
||||
| --------------------------------------------------- | ------------------------------------------- | ------ |
|
||||
| [The basics](./basics.rs) | A few basic examples to preview Dioxus | 🛠 |
|
||||
| [fine grained reactivity](./signals.rs) | Escape `diffing` by writing values directly | 🛠 |
|
||||
| [Global State Management](./statemanagement.rs) | Share state between components | 🛠 |
|
||||
| [Virtual Refs]() | Cross-platform imperative elements | 🛠 |
|
||||
| [Inline Styles](./inline-styles.rs) | Define styles for elements inline | 🛠 |
|
||||
| [Conditional Rendering](./conditional-rendering.rs) | Hide/Show elements using conditionals | ✅ |
|
||||
|
||||
These examples are not necessarily meant to be run, but rather serve as a reference for the given functionality.
|
||||
|
||||
| Example | What it does | Status |
|
||||
| --------------------------------------------------- | ----------------------------------------------- | ------ |
|
||||
| [The basics](./basics.rs) | A few basic examples to preview Dioxus | 🛠 |
|
||||
| [fine grained reactivity](./signals.rs) | Escape `diffing` by writing values directly | 🛠 |
|
||||
| [Global State Management](./statemanagement.rs) | Share state between components | 🛠 |
|
||||
| [Virtual Refs]() | Cross-platform imperative elements | 🛠 |
|
||||
| [Inline Styles](./inline-styles.rs) | Define styles for elements inline | 🛠 |
|
||||
| [Conditional Rendering](./conditional-rendering.rs) | Hide/Show elements using conditionals | ✅ |
|
||||
| [Maps/Iterators](./iterators.rs) | Use iterators in the rsx! macro | 🛠 |
|
||||
| [Render To string](./tostring.rs) | Render a mounted virtualdom to a string | 🛠 |
|
||||
| [Component Children](./children.rs) | Pass children into child components | 🛠 |
|
||||
| [Function Driven children]() | Pass functions to make VNodes | 🛠 |
|
||||
| [Memoization & Borrowed Data](./memo.rs) | Suppress renders, borrow from parents | ✅ |
|
||||
| [Fragments](./fragments.rs) | Support root-less element groups | ✅ |
|
||||
| [Null/None Components](./empty.rs) | Return nothing! | 🛠 |
|
||||
| [Spread Pattern for props](./spreadpattern.rs) | Manually specify and override props | ✅ |
|
||||
| [Controlled Inputs](./controlled-inputs.rs) | this does | 🛠 |
|
||||
| [Custom Elements]() | Define custom elements | 🛠 |
|
||||
| [Web Components]() | Custom elements to interface with WebComponents | 🛠 |
|
||||
| [Testing And debugging]() | this does | 🛠 |
|
||||
| [Asynchronous Data]() | Using suspense to wait for data | 🛠 |
|
||||
| [Fiber/Scheduled Rendering]() | this does | 🛠 |
|
||||
| [CSS Compiled Styles]() | this does | 🛠 |
|
||||
| [Anti-patterns](./antipatterns.rs) | A collection of discouraged patterns | ✅ |
|
||||
| [Complete rsx reference](./rsx_usage.rs) | A complete reference for all rsx! usage | ✅ |
|
||||
| [Event Listeners](./listener.rs) | Attach closures to events on elements | ✅ |
|
||||
|
||||
These web-specific examples must be run with `dioxus-cli` using `dioxus develop --example XYZ`
|
||||
|
||||
| Example | What it does |
|
||||
| ------- | ------------ |
|
||||
| asd | this does |
|
||||
| asd | this does |
|
||||
@@ -1,24 +0,0 @@
|
||||
#![allow(unused, non_upper_case_globals)]
|
||||
|
||||
use dioxus_core::prelude::*;
|
||||
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
let (name, set_name) = use_state(&cx, || "...?");
|
||||
|
||||
cx.render(rsx!(
|
||||
div {
|
||||
h1 { "Hello, {name}" }
|
||||
// look ma - we can rsx! and html! together
|
||||
{["jack", "jill"].iter().map(|f| html!(<button onclick={move |_| set_name(f)}> "{f}" </button>))}
|
||||
}
|
||||
))
|
||||
};
|
||||
|
||||
pub fn render<'src, 'a, F: for<'b> FnOnce(&'b NodeFactory<'src>) -> VNode<'src> + 'src + 'a, P>(
|
||||
cx: &'a Context<'src, P>,
|
||||
lazy_nodes: LazyNodes<'src, F>,
|
||||
) -> VNode<'src> {
|
||||
cx.render(lazy_nodes)
|
||||
}
|
||||
@@ -21,10 +21,10 @@ fn main() {}
|
||||
/// Antipattern: Iterators without keys
|
||||
/// -----------------------------------
|
||||
///
|
||||
/// This is considered an anti-pattern for performance reasons. Dioxus must diff your current and old layout and must
|
||||
/// This is considered an anti-pattern for performance reasons. Dioxus will diff your current and old layout and must
|
||||
/// take a slower path if it can't correlate old elements with new elements. Lists are particularly susceptible to the
|
||||
/// "slow" path, so you're strongly encouraged to provide a unique ID stable between renders. Additionally, providing
|
||||
/// the *wrong* keys is even worse. Keys should be:
|
||||
/// the *wrong* keys is even worse - props might be assigned to the wrong components! Keys should be:
|
||||
/// - Unique
|
||||
/// - Stable
|
||||
/// - Predictable
|
||||
@@ -39,7 +39,7 @@ static AntipatternNoKeys: FC<NoKeysProps> = |cx| {
|
||||
rsx!(in cx, ul {
|
||||
{cx.data.iter().map(|(k, v)| rsx!(li { "List item: {v}" }))}
|
||||
});
|
||||
// Like this:
|
||||
// RIGHT: Like this:
|
||||
rsx!(in cx, ul {
|
||||
{cx.data.iter().map(|(k, v)| rsx!(li { key: "{k}", "List item: {v}" }))}
|
||||
})
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
//! Example: Children
|
||||
//! -----------------
|
||||
//!
|
||||
//! Dioxus supports passing children in from the parent. These children are allocated in the parent and just forced
|
||||
//! into the child. Components that pass in children may not be safely memoized, though in practice its rare for a
|
||||
//! change in a parent to not result in a different set of children.
|
||||
//!
|
||||
//! In Dioxus, children can *only be a list*. Unlike React, you cannot pass in functions or arbitrary data. This is
|
||||
//! partially a limitaiton in having static types, but is rather intentional to encourage the use of attributes where
|
||||
//! arbitrary child data might normally be used. Check out the `function driven children` example for how to adopt your
|
||||
//! React pattern for Dioxus' semantics.
|
||||
//!
|
||||
//! Dioxus will let you use the `children` method more than once - and it's semantically *okay* - but you'll likely
|
||||
//! ruin your page if you try to clone elements in this way. Under the hood, Dioxus shares a "mounted ID" for each node,
|
||||
//! and mounting the same VNode in two places will overwrite the first mounted ID. This will likely lead to dead elements.
|
||||
//!
|
||||
//! In the future, this might become a runtime error, so consider it an error today.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static App: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
Banner {
|
||||
p { "Some Content1" }
|
||||
}
|
||||
Banner {
|
||||
p { "Some Content2" }
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
static Banner: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "This is a great banner!" }
|
||||
div { class: "content"
|
||||
{cx.children()}
|
||||
}
|
||||
footer { "Wow, what a great footer" }
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
//! Example: Conditional Rendering
|
||||
//! ------------------------------
|
||||
//!
|
||||
//! This example shows how to hide or show elements using conditional rendering.
|
||||
//!
|
||||
//! Often times you might want to display a different UI given some sort of condition. This is called "conditonal rendering".
|
||||
//! In Dioxus, you can perform conditional rendering with optionals or matching.
|
||||
//!
|
||||
//! The rsx! and html! macro accepts anything that is `IntoIter<Item = impl IntoVnode>`. Options and Results both implement
|
||||
//! IntoIter for impl VNode, so you can use option/result for conditional rendering.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {}
|
||||
|
||||
// Convert a boolean conditional into a hide/show
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps {
|
||||
should_show: bool,
|
||||
}
|
||||
static Example: FC<MyProps> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
{cx.should_show.then(|| rsx!{
|
||||
h1 { "showing the title!" }
|
||||
})}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// Convert a boolean conditional into an either/or
|
||||
// Because rsx! is lazy (produces a closure), we cannot use it in two branch arms. To use it in matching/branching, we
|
||||
// must render it.
|
||||
//
|
||||
// Dioxus will let you render any `LazyNodes` into a `VNode` with `cx.render`. `rsx!` also supports the `in cx` syntax
|
||||
// which will do essentially the same thing as `cx.render`.
|
||||
//
|
||||
// In short:
|
||||
// `rsx!(in cx, ...)` is shorthand for `cx.render(rsx!(...))`
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps1 {
|
||||
should_show: bool,
|
||||
}
|
||||
static Example1: FC<MyProps1> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
// With matching
|
||||
{match cx.should_show {
|
||||
true => cx.render(rsx!(div {"it is true!"})),
|
||||
false => rsx!(in cx, div {"it is false!"}),
|
||||
}}
|
||||
|
||||
// or with just regular conditions
|
||||
{if cx.should_show {
|
||||
rsx!(in cx, div {"it is true!"})
|
||||
} else {
|
||||
rsx!(in cx, div {"it is false!"})
|
||||
}}
|
||||
|
||||
// or with optional chaining
|
||||
{
|
||||
cx.should_show
|
||||
.then(|| rsx!(in cx, div {"it is false!"}))
|
||||
.unwrap_or_else(|| rsx!(in cx, div {"it is false!"}))
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
/// Matching can be expanded
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Color {
|
||||
Green,
|
||||
Yellow,
|
||||
Red,
|
||||
}
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps2 {
|
||||
color: Color,
|
||||
}
|
||||
static Example2: FC<MyProps2> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
{match cx.color {
|
||||
Color::Green => rsx!(in cx, div {"it is Green!"}),
|
||||
Color::Yellow => rsx!(in cx, div {"it is Yellow!"}),
|
||||
Color::Red => rsx!(in cx, div {"it is Red!"}),
|
||||
}}
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
//! Example: Null/None Children
|
||||
//! ---------------------------
|
||||
//!
|
||||
//! This is a simple pattern that allows you to return no elements!
|
||||
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
//! Example: Fragments
|
||||
//! ------------------
|
||||
//!
|
||||
//! Dioxus can return multiple elements without a container through the use of the VNode called a "Fragment". Fragments do not
|
||||
//! have a mounted root and are inserted inline with their siblings. There are three ways of creating fragments as outlined
|
||||
//! in the examples below:
|
||||
//! - By returning multiple elements in Rsx!
|
||||
//! - By using the `Fragment` component
|
||||
//! - By using the fragment() method on the node factory
|
||||
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
// Returning multiple elements with rsx! or html!
|
||||
static Example1: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
h1 { }
|
||||
h2 { }
|
||||
h3 { }
|
||||
// {}
|
||||
// "hello world"
|
||||
})
|
||||
};
|
||||
|
||||
// Using the Fragment component
|
||||
static Example2: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
Fragment {
|
||||
div {}
|
||||
div {}
|
||||
"asd"
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
// Using the `fragment` method on the NodeFactory
|
||||
static Example3: FC<()> = |cx| {
|
||||
cx.render(LazyNodes::new(move |fac: &NodeFactory| {
|
||||
fac.fragment_builder(None, |list| {
|
||||
list.add_child(fac.text(format_args!("A")))
|
||||
.add_child(fac.text(format_args!("B")))
|
||||
.finish()
|
||||
})
|
||||
}))
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
//! Example: Listeners
|
||||
//! ------------------
|
||||
//!
|
||||
//! This example demonstrates the various ways listeners may be used in Dioxus.
|
||||
//! Listeners may be at most `FnMut` - but not `FnOnce`.
|
||||
//! Listeners may borrow the lifetime of cx (children and hooks), but not of local (stack) data.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {}
|
||||
|
||||
/// We can use `set_name` in multiple closures; the closures automatically *copy* the reference to set_name.
|
||||
static ButtonList: FC<()> = |cx| {
|
||||
let (name, set_name) = use_state(&cx, || "...?");
|
||||
|
||||
let names = ["jack", "jill", "john", "jane"]
|
||||
.iter()
|
||||
.map(move |n| rsx!(button { onclick: move |_| set_name(n), "{n}" }));
|
||||
|
||||
cx.render(rsx!(
|
||||
div {
|
||||
h1 { "Hello, {name}" }
|
||||
{names}
|
||||
}
|
||||
))
|
||||
};
|
||||
|
||||
/// This shows how listeners may be without a visible change in the display.
|
||||
/// Check the console.
|
||||
static NonUpdatingEvents: FC<()> = |cx| {
|
||||
rsx!(in cx, div {
|
||||
button {
|
||||
onclick: move |_| log::info!("Did not cause any updates!")
|
||||
"Click me to log!"
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
static DisablePropogation: FC<()> = |cx| {
|
||||
rsx!(in cx,
|
||||
div {
|
||||
onclick: move |_| log::info!("event propogated to the div!")
|
||||
button {
|
||||
onclick: move |evt| {
|
||||
log::info!("Button will allow propogation");
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
//! Example: Memoization
|
||||
//! --------------------
|
||||
//!
|
||||
//! This example showcases how memoization works in Dioxus.
|
||||
//!
|
||||
//! Memoization is the process in which Dioxus skips diffing child components if their props don't change.
|
||||
//! In React, components are never memoized unless wrapped in `memo` or configured with `shouldComponentUpdate`.
|
||||
//!
|
||||
//! Due to the safety guarantees of Rust, we can automatically memoize components in some circumstances. Whenever a
|
||||
//! component's properties are valid for the `'static` lifetime, Dioxus will automatically compare the props before
|
||||
//! diffing the component. If the props don't change (according to PartialEq), the component will not be re-rendered.
|
||||
//!
|
||||
//! However, if the props use some generics or borrow from their parent, then Dioxus can't safely supress updates,
|
||||
//! and is forced to render the child. If you think that this behavior is wrong for your usecase, you can implement
|
||||
//! the memo method yourself, but beware, doing so is UNSAFE and may cause issues if you do it wrong.
|
||||
//!
|
||||
//! If you want to gain that little bit extra performance, consider using global state management, signals, or
|
||||
//! memoized collections like im-rc which are designed for this use case.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
// By default, components with no props are always memoized.
|
||||
// A props of () is considered empty.
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div { "100% memoized!" }
|
||||
})
|
||||
};
|
||||
|
||||
// These props do not borrow any content, and therefore can be safely memoized.
|
||||
// However, the parent *must* create a new string on every render.
|
||||
// Notice how these props implement PartialEq - this is required for 'static props
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps1 {
|
||||
name: String,
|
||||
}
|
||||
|
||||
static Example1: FC<MyProps1> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div { "100% memoized! {cx.name}" }
|
||||
})
|
||||
};
|
||||
|
||||
// These props do not borrow any content, and therefore can be safely memoized.
|
||||
// In contrast with the `String` example, these props use `Rc<str>` which operates similar to strings in JavaScript.
|
||||
// These strings cannot be modified, but may be cheaply shared in many places without issue.
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps2 {
|
||||
name: std::rc::Rc<str>,
|
||||
}
|
||||
|
||||
static Example2: FC<MyProps2> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div { "100% memoized! {cx.name}" }
|
||||
})
|
||||
};
|
||||
|
||||
// These props *do* borrow any content, and therefore cannot be safely memoized!.
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps3<'a> {
|
||||
name: &'a str,
|
||||
}
|
||||
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
|
||||
// Using the `static Example: FC<()>` pattern _will_ specify a lifetime, but that lifetime will be static which might
|
||||
// not exactly be what you want
|
||||
fn Example3<'a>(cx: Context<'a, MyProps3<'a>>) -> VNode {
|
||||
cx.render(rsx! {
|
||||
div { "Not memoized! {cx.name}" }
|
||||
})
|
||||
}
|
||||
|
||||
// These props *do* borrow any content, and therefore cannot be safely memoized!.
|
||||
// However, they cannot be compared, so we don't need the PartialEq flag.
|
||||
#[derive(Props)]
|
||||
struct MyProps4<'a> {
|
||||
onhandle: &'a dyn Fn(),
|
||||
}
|
||||
|
||||
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
|
||||
fn Example4<'a>(cx: Context<'a, MyProps4<'a>>) -> VNode {
|
||||
cx.render(rsx! {
|
||||
div { "Not memoized!", onclick: move |_| (cx.onhandle)() }
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
mod iterator;
|
||||
mod memo;
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
//! Example: Spread pattern for Components
|
||||
//! --------------------------------------
|
||||
//!
|
||||
//! Dioxus supports the "spread" pattern for manually building a components properties. This is useful when props
|
||||
//! are passed down from a parent, or it's more ergonomic to construct props from outside the rsx! macro.
|
||||
//!
|
||||
//! To use the spread pattern, simply pass ".." followed by a Rust epxression. This pattern also supports overriding
|
||||
//! values, using the manual props as the base and then modifying fields specified with non-spread attributes.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static App: FC<()> = |cx| {
|
||||
let props = MyProps {
|
||||
count: 0,
|
||||
live: true,
|
||||
name: "Dioxus",
|
||||
};
|
||||
cx.render(rsx! {
|
||||
Example { ..props, count: 10, div {"child"} }
|
||||
})
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
struct MyProps {
|
||||
count: u32,
|
||||
live: bool,
|
||||
name: &'static str,
|
||||
}
|
||||
|
||||
static Example: FC<MyProps> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "Hello, {cx.name}"}
|
||||
h3 {"Are we alive? {cx.live}"}
|
||||
p {"Count is {cx.count}"}
|
||||
{ cx.children() }
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
File renamed without changes.
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
use dioxus::prelude::*;
|
||||
fn main() {}
|
||||
|
||||
static Example: FC<()> = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
//! Example: Web Components
|
||||
//! -----------------------
|
||||
//!
|
||||
//! Web components are a flavor of html elements that can be user-defined.
|
||||
//! See: https://www.webcomponents.org for more information.
|
||||
//!
|
||||
//! Users who use webcomponents typically don't use Dioxus. However, if you would like to use webcomponents in Dioxus,
|
||||
//! you can easily create a new custom element with compile-time correct wrappers around the webcomponent.
|
||||
//!
|
||||
//! We don't support building new webcomponents with Dioxus, however.
|
||||
//!
|
||||
|
||||
use dioxus::{builder::ElementBuilder, prelude::NodeFactory};
|
||||
|
||||
fn main() {}
|
||||
|
||||
// TODO
|
||||
struct MyEle<'a, 'b> {
|
||||
el: ElementBuilder<'a, 'b>,
|
||||
fac: &'b NodeFactory<'a>,
|
||||
}
|
||||
@@ -120,7 +120,7 @@ static Example: FC<()> = |cx| {
|
||||
{if true {
|
||||
rsx!(in cx, h1 {"Top text"})
|
||||
} else {
|
||||
cx.render(rsx!( h1 {"Bottom text"}))
|
||||
rsx!(in cx, h1 {"Bottom text"})
|
||||
}}
|
||||
|
||||
// returning "None" is a bit noisy... but rare in practice
|
||||
@@ -168,7 +168,13 @@ static Example: FC<()> = |cx| {
|
||||
rsx!(Taller { ..props })
|
||||
}}
|
||||
|
||||
// Can take children
|
||||
// Spreading can also be overridden manually
|
||||
Taller {
|
||||
..TallerProps { a: "ballin!" }
|
||||
a: "not ballin!"
|
||||
}
|
||||
|
||||
// Can take children too!
|
||||
Taller { a: "asd", div {"hello world!"} }
|
||||
}
|
||||
})
|
||||
|
||||
+28
-23
@@ -1,26 +1,31 @@
|
||||
//! A Showcase of all the useful examples
|
||||
//!
|
||||
//!
|
||||
//! Example: Reference Showcase
|
||||
//! ---------------------------
|
||||
//!
|
||||
//! This example provides a cute interface for browsing the reference examples.
|
||||
|
||||
fn main() {
|
||||
use_css_consumer(&cx, "mystyle");
|
||||
|
||||
// at the global head of the app
|
||||
use_css_provider(&cx, |cfg| {});
|
||||
use_recoil_provider(&cx, |cfg| {});
|
||||
|
||||
let recoil = use_recoil_api(&cx, |_| {});
|
||||
use_websocket_connection(&cx, move |cfg| {
|
||||
cfg.on_receive(move |event| match event.data::<Msg>() {
|
||||
Ok(msg) => match msg {
|
||||
a => recoil.set(&ATOM, 10),
|
||||
c => recoil.set(&ATOM, 20),
|
||||
_ => {}
|
||||
},
|
||||
Err(e) => {}
|
||||
});
|
||||
cfg.on_close(move |event| {});
|
||||
cfg.on_open(move |event| {});
|
||||
});
|
||||
mod reference {
|
||||
mod antipatterns;
|
||||
mod basics;
|
||||
mod children;
|
||||
mod conditional_rendering;
|
||||
mod controlled_inputs;
|
||||
mod custom_elements;
|
||||
mod empty;
|
||||
mod fiber;
|
||||
mod fragments;
|
||||
mod global_css;
|
||||
mod inline_styles;
|
||||
mod iterators;
|
||||
mod listener;
|
||||
mod memo;
|
||||
mod noderefs;
|
||||
mod signals;
|
||||
mod spreadpattern;
|
||||
mod statemanagement;
|
||||
mod suspense;
|
||||
mod testing;
|
||||
mod tostring;
|
||||
mod webcomponents;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Reference in new issue
Block a user