123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- //! Demonstrate that borrowed data is possible as a property type
- //! Borrowing (rather than cloning) is very important for speed and ergonomics.
- //!
- //! It's slightly more advanced than just cloning, but well worth the investment.
- //!
- //! If you use the FC macro, we handle the lifetimes automatically, making it easy to write efficient & performant components.
- fn main() {}
- use dioxus_core::prelude::*;
- struct Props {
- items: Vec<ListItem>,
- }
- #[derive(PartialEq)]
- struct ListItem {
- name: String,
- age: u32,
- }
- fn app(ctx: Context, props: &Props) -> DomTree {
- let (_f, setter) = use_state(&ctx, || 0);
- ctx.render(dioxus::prelude::LazyNodes::new(move |c| {
- let mut root = builder::ElementBuilder::new(c, "div");
- for child in &props.items {
- // notice that the child directly borrows from our vec
- // this makes lists very fast (simply views reusing lifetimes)
- // <ChildItem item=child hanldler=setter />
- root = root.child(builder::virtual_child(
- c,
- ChildItem,
- // create the props with nothing but the fc<T>
- fc_to_builder(ChildItem)
- .item(child)
- .item_handler(setter)
- .build(),
- ));
- }
- root.finish()
- }))
- }
- type StateSetter<T> = dyn Fn(T);
- // struct StateSetter<T>(dyn Fn(T));
- // impl<T> PartialEq for StateSetter<T> {
- // fn eq(&self, other: &Self) -> bool {
- // self as *const _ == other as *const _
- // }
- // }
- // props should derive a partialeq implementation automatically, but implement ptr compare for & fields
- #[derive(Props)]
- struct ChildProps<'a> {
- // Pass down complex structs
- item: &'a ListItem,
- // Even pass down handlers!
- item_handler: &'a StateSetter<i32>,
- }
- impl PartialEq for ChildProps<'_> {
- fn eq(&self, _other: &Self) -> bool {
- // assume the dyn fn is never stable -
- // wrap with use_callback if it's an issue for you
- false
- }
- }
- fn ChildItem(_ctx: Context, _props: &ChildProps) -> DomTree {
- todo!()
- // ctx.render(rsx! {
- // div {
- // item: child,
- // handler: setter,
- // abc: 123,
- // onclick: props.item_handler,
- // h1 { "abcd123" }
- // h2 { "abcd123" }
- // div {
- // "abcd123"
- // h2 { }
- // p { }
- // },
- // }
- // })
- }
- /*
- rsx! {
- ChildItem {
- // props
- item: child, handler: setter,
- // children
- div { class:"abcd", abc: 123 },
- div { class:"abcd", abc: 123 },
- // Auto-text coercion
- "eyo matie {abc}",
- // Anything that accepts Into<VChild>
- {},
- }
- }
- // dreaming of this syntax
- #[derive(Properties)]
- struct ChildProps<'a> {
- username: &'a str,
- item_handler: &'a dyn Fn(i32),
- }
- fn child_item(ctx: Context, props: &ChildProps) -> DomTree {
- ctx.render(rsx! {
- div {
- class: "abc123",
- abc: 123,
- onclick: props.item_handler,
- h1 { "Hello, {props.username}!" },
- h2 { "Welcome the RSX syntax" },
- div {
- h3 { "This is a subheader" }
- button {
- onclick: props.handler,
- "This is a button"
- }
- "This is child text"
- },
- }
- })
- }
- // This is also nice
- #[dioxus::component]
- static CHILD: FC = |ctx, username: &str, handler: &dyn Fn(i32)| {
- ctx.render(rsx! {
- div {
- class: "abc123",
- abc: 123,
- onclick: handler,
- h1 { "Hello, {username}!" },
- h2 { "Welcome the RSX syntax" },
- div {
- h3 { "This is a subheader" }
- button {
- onclick: props.handler,
- "This is a button"
- }
- "This is child text"
- },
- }
- })
- }
- Menlo, Monaco, 'Courier New', monospace
- struct Item {
- name: String,
- content: String,
- }
- #[dioxus::live_component]
- static CHILD: FC = |ctx, username: &str, handler: &dyn Fn(i32)| {
- // return lazy nodes or
- let ssr = ctx.suspend(async {
- let data = fetch("https://google.com")
- .await?
- .json::<Item>()
- .await?;
- rsx! {
- div {
- h1 { "Welcome: {data.name}" }
- p { "Content: \n {data.content}" }
- }
- }
- });
- ctx.render(rsx! {
- div {
- class: "abc123",
- abc: 123,
- onclick: handler,
- h1 { "Hello, {username}!" },
- h2 { "Welcome the RSX syntax" },
- div {
- h3 { "This is a subheader" }
- button {
- onclick: props.handler,
- "This is a button"
- }
- {ssr}
- },
- }
- })
- }
- */
|