Feat: found a fast solution to hook state
This commit is contained in:
1 parent
62d4ad5878
commit
4d01436c3f
9 files changed
+759
-85
No files matched your search
@@ -1,41 +1,84 @@
|
||||
#![allow(unused, non_upper_case_globals, non_snake_case)]
|
||||
use bumpalo::Bump;
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core::{nodebuilder::*, virtual_dom::DomTree};
|
||||
use dioxus_core::{nodebuilder::*, virtual_dom::Properties};
|
||||
use std::{collections::HashMap, future::Future, marker::PhantomData};
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
let mut vdom = VirtualDom::new_with_props(
|
||||
component,
|
||||
Props {
|
||||
blah: false,
|
||||
text: "blah",
|
||||
},
|
||||
);
|
||||
|
||||
vdom.progress();
|
||||
|
||||
let somet = String::from("asd");
|
||||
let text = somet.as_str();
|
||||
|
||||
/*
|
||||
this could be auto-generated via the macro
|
||||
this props is allocated in this
|
||||
but the component and props would like need to be cached
|
||||
we could box this fn, abstracting away the props requirement and just keep the entrance and allocator requirement
|
||||
How do we keep cached things around?
|
||||
Need some sort of caching mechanism
|
||||
|
||||
how do we enter into a childscope from a parent scope?
|
||||
|
||||
Problems:
|
||||
1: Comp props need to be stored somewhere so we can re-evalute components when they receive updates
|
||||
2: Trees are not evaluated
|
||||
|
||||
*/
|
||||
let example_caller = move |ctx: &Bump| {
|
||||
todo!()
|
||||
// let p = Props { blah: true, text };
|
||||
// let c = Context { props: &p };
|
||||
// let r = component(&c);
|
||||
};
|
||||
|
||||
// check the edit list
|
||||
}
|
||||
|
||||
// ~~~ Text shared between components via props can be done with lifetimes! ~~~
|
||||
// Super duper efficient :)
|
||||
struct Props {
|
||||
struct Props<'src> {
|
||||
blah: bool,
|
||||
text: String,
|
||||
text: &'src str,
|
||||
}
|
||||
impl<'src> Properties for Props<'src> {
|
||||
fn new() -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn Component<'a>(ctx: &'a Context<Props>) -> VNode<'a> {
|
||||
fn component<'a>(ctx: &'a Context<Props>) -> VNode<'a> {
|
||||
// Write asynchronous rendering code that immediately returns a "suspended" VNode
|
||||
// The concurrent API will then progress this component when the future finishes
|
||||
// You can suspend the entire component, or just parts of it
|
||||
let product_list = ctx.suspend(async {
|
||||
// Suspend the rendering that completes when the future is done
|
||||
match fetch_data().await {
|
||||
Ok(data) => html! {<div> </div>},
|
||||
Err(_) => html! {<div> </div>},
|
||||
Ok(data) => html! { <div> </div>},
|
||||
Err(_) => html! { <div> </div>},
|
||||
}
|
||||
});
|
||||
|
||||
ctx.view(html! {
|
||||
<div>
|
||||
// <h1> "Products" </h1>
|
||||
// // Subnodes can even be suspended
|
||||
// // When completely rendered, they won't cause the component itself to re-render, just their slot
|
||||
// <p> { product_list } </p>
|
||||
</div>
|
||||
})
|
||||
todo!()
|
||||
// ctx.view(html! {
|
||||
// <div>
|
||||
// // <h1> "Products" </h1>
|
||||
// // // Subnodes can even be suspended
|
||||
// // // When completely rendered, they won't cause the component itself to re-render, just their slot
|
||||
// // <p> { product_list } </p>
|
||||
// </div>
|
||||
// })
|
||||
}
|
||||
|
||||
fn BuilderComp(ctx: Context<Props>) -> VNode {
|
||||
fn BuilderComp<'a>(ctx: &'a Context<'a, Props>) -> VNode<'a> {
|
||||
// VNodes can be constructed via a builder or the html! macro
|
||||
// However, both of these are "lazy" - they need to be evaluated (aka, "viewed")
|
||||
// We can "view" them with Context for ultimate speed while inside components
|
||||
@@ -43,7 +86,7 @@ fn BuilderComp(ctx: Context<Props>) -> VNode {
|
||||
div(bump)
|
||||
.attr("class", "edit")
|
||||
.child(text("Hello"))
|
||||
.child(text(ctx.props.text.as_str()))
|
||||
.child(text(ctx.props.text))
|
||||
.finish()
|
||||
})
|
||||
}
|
||||
@@ -79,7 +122,7 @@ fn EffcComp(ctx: &Context, name: &str) -> VNode {
|
||||
})
|
||||
}
|
||||
|
||||
fn FullySuspended(ctx: Context<Props>) -> VNode {
|
||||
fn FullySuspended<'a>(ctx: &'a Context<Props>) -> VNode<'a> {
|
||||
ctx.suspend(async {
|
||||
let i: i32 = 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use bumpalo::Bump;
|
||||
use dioxus_core::prelude::{Context, VNode};
|
||||
use std::{any::Any, cell::RefCell, rc::Rc};
|
||||
use std::{borrow::Borrow, sync::atomic::AtomicUsize};
|
||||
use typed_arena::Arena;
|
||||
|
||||
fn main() {
|
||||
let ar = Arena::new();
|
||||
|
||||
(0..5).for_each(|f| {
|
||||
// Create the temporary context obect
|
||||
let c = Context {
|
||||
_p: std::marker::PhantomData {},
|
||||
props: (),
|
||||
idx: 0.into(),
|
||||
arena: &ar,
|
||||
hooks: RefCell::new(Vec::new()),
|
||||
};
|
||||
|
||||
component(c);
|
||||
});
|
||||
}
|
||||
|
||||
// we need to do something about props and context being borrowed from different sources....
|
||||
// kinda anooying
|
||||
/// use_ref creates a new value when the component is created and then borrows that value on every render
|
||||
fn component(ctx: Context<()>) {
|
||||
(0..10).for_each(|f| {
|
||||
let r = use_ref(&ctx, move || f);
|
||||
assert_eq!(*r, f);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn use_ref<'a, P, T: 'static>(
|
||||
ctx: &'a Context<'a, P>,
|
||||
initial_state_fn: impl FnOnce() -> T + 'static,
|
||||
) -> &'a T {
|
||||
ctx.use_hook(
|
||||
|| initial_state_fn(), // initializer
|
||||
|state| state, // runner, borrows the internal value
|
||||
|b| {}, // tear down
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user