فهرست منبع

Remove a number of hooks

Jonathan Kelley 1 سال پیش
والد
کامیت
b291a5c0b0

+ 0 - 22
examples/callback.rs

@@ -1,22 +0,0 @@
-use dioxus::prelude::*;
-
-fn main() {
-    dioxus_desktop::launch(app);
-}
-
-fn app() -> Element {
-    let onclick = use_callback!(move |_| async move {
-        let res = reqwest::get("https://dog.ceo/api/breeds/list/all")
-            .await
-            .unwrap()
-            .text()
-            .await
-            .unwrap();
-
-        println!("{res:#?}, ");
-    });
-
-    rsx! {
-        button { onclick, "Click me!" }
-    }
-}

+ 3 - 3
examples/crm.rs

@@ -97,7 +97,7 @@ fn ClientAdd() -> Element {
                     label { "for": "first_name", "First Name" }
                     input {
                         id: "first_name",
-                        "type": "text",
+                        r#type: "text",
                         placeholder: "First Name…",
                         required: "",
                         value: "{first_name}",
@@ -109,7 +109,7 @@ fn ClientAdd() -> Element {
                     label { "for": "last_name", "Last Name" }
                     input {
                         id: "last_name",
-                        "type": "text",
+                        r#type: "text",
                         placeholder: "Last Name…",
                         required: "",
                         value: "{last_name}",
@@ -128,7 +128,7 @@ fn ClientAdd() -> Element {
                 }
 
                 div { class: "pure-controls",
-                    button { "type": "submit", class: "pure-button pure-button-primary", "Save" }
+                    button { r#type: "submit", class: "pure-button pure-button-primary", "Save" }
                     Link { to: Route::ClientList {}, class: "pure-button pure-button-primary red", "Cancel" }
                 }
             }

+ 1 - 4
examples/dog_app.rs

@@ -29,10 +29,7 @@ fn app() -> Element {
                     ul { flex: "50%",
                         for cur_breed in breed_list.message.keys().take(10) {
                             li { key: "{cur_breed}",
-                                button {
-                                    onclick: move |_| breed.set(cur_breed.clone()),
-                                    "{cur_breed}"
-                                }
+                                button { onclick: move |_| breed.set(cur_breed.clone()), "{cur_breed}" }
                             }
                         }
                     }

+ 0 - 48
packages/hooks/src/use_callback.rs

@@ -1,48 +0,0 @@
-use dioxus_core::ScopeState;
-use std::future::Future;
-
-#[macro_export]
-macro_rules! use_callback {
-    // ($cx:ident, || || $($rest:tt)*) => { use_callback( $cx, (), |_| $($rest)* ) };
-    // ($cx:ident, || || $($rest:tt)*) => { use_callback( $cx, (), |_| $($rest)* ) };
-    ($cx:ident, || $($rest:tt)*) => {
-        use_callback(
-            $cx,
-            move || $($rest)*
-        )
-    };
-    ($cx:ident, |$($args:tt),* | $($rest:tt)*) => {
-        use_callback(
-            $cx,
-            move || $($rest)*
-        )
-    };
-    ($cx:ident, $($rest:tt)*) => {
-        use_callback(
-            $cx,
-            move || $($rest)*
-        )
-    };
-}
-
-pub fn use_callback<T, R, F>(, make: impl FnOnce() -> R) -> impl FnMut(T) + '_
-where
-    R: FnMut(T) -> F + 'static,
-    F: Future<Output = ()> + 'static,
-{
-    let mut hook = make();
-
-    move |evt| cx.spawn(hook(evt))
-}
-
-fn _it_works() {
-    let _p = use_callback(|| {
-        |()| async {
-            //
-        }
-    });
-
-    // let p = use_callback!(|| |evt| async {
-    //     //
-    // });
-}

+ 0 - 75
packages/hooks/src/use_const.rs

@@ -1,75 +0,0 @@
-use std::rc::Rc;
-
-use dioxus_core::prelude::*;
-
-/// Store constant state between component renders.
-///
-/// UseConst allows you to store state that is initialized once and then remains constant across renders.
-/// You can only get an immutable reference after initalization.
-/// This can be useful for values that don't need to update reactively, thus can be memoized easily
-///
-/// ```rust, ignore
-/// struct ComplexData(i32);
-///
-/// fn Component() -> Element {
-///   let id = use_const(|| ComplexData(100));
-///
-///   rsx! {
-///     div { "{id.0}" }
-///   })
-/// }
-/// ```
-#[must_use]
-pub fn use_const<T: 'static>
-    initial_state_fn: impl FnOnce() -> T,
-) -> &UseConst<T> {
-    cx.use_hook(|| UseConst {
-        value: Rc::new(initial_state_fn()),
-    })
-}
-
-#[derive(Clone)]
-pub struct UseConst<T> {
-    value: Rc<T>,
-}
-
-impl<T> PartialEq for UseConst<T> {
-    fn eq(&self, other: &Self) -> bool {
-        Rc::ptr_eq(&self.value, &other.value)
-    }
-}
-
-impl<T: core::fmt::Display> core::fmt::Display for UseConst<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        self.value.fmt(f)
-    }
-}
-
-impl<T> UseConst<T> {
-    pub fn get_rc(&self) -> &Rc<T> {
-        &self.value
-    }
-}
-
-impl<T> std::ops::Deref for UseConst<T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        self.value.as_ref()
-    }
-}
-
-#[test]
-fn use_const_makes_sense() {
-    #[allow(unused)]
-
-    fn app() -> Element {
-        let const_val = use_const(|| vec![0, 1, 2, 3]);
-
-        assert!(const_val[0] == 0);
-
-        // const_val.remove(0); // Cannot Compile, cannot get mutable reference now
-
-        None
-    }
-}

+ 0 - 174
packages/hooks/src/use_effect.rs

@@ -1,174 +0,0 @@
-use dioxus_core::{ScopeState, Task};
-use std::{
-    any::Any,
-    cell::{Cell, RefCell},
-    future::Future,
-    rc::Rc,
-};
-
-use crate::UseFutureDep;
-
-/// A hook that provides a future that executes after the hooks have been applied.
-///
-/// Whenever the hooks dependencies change, the future will be re-evaluated.
-/// If a future is pending when the dependencies change, the previous future
-/// will be allowed to continue.
-///
-/// **Note:** If your dependency list is always empty, use [`use_on_create`](crate::use_on_create).
-///
-/// ## Arguments
-///
-/// - `dependencies`: a tuple of references to values that are `PartialEq` + `Clone`.
-/// - `future`: a closure that takes the `dependencies` as arguments and returns a `'static` future. That future may return nothing or a closure that will be executed when the dependencies change to clean up the effect.
-///
-/// ## Examples
-///
-/// ```rust, no_run
-/// # use dioxus::prelude::*;
-/// #[component]
-/// fn Profile(id: usize) -> Element {
-///     let name = use_signal(|| None);
-///
-///     // Only fetch the user data when the id changes.
-///     use_effect((id,), |(id,)| {
-///         to_owned![name];
-///         async move {
-///             let user = fetch_user(id).await;
-///             name.set(user.name);
-///         }
-///     });
-///
-///     // Only fetch the user data when the id changes.
-///     use_effect((id,), |(id,)| {
-///         to_owned![name];
-///         async move {
-///             let user = fetch_user(id).await;
-///             name.set(user.name);
-///             move || println!("Cleaning up from {}", id)
-///         }
-///     });
-///
-///     let name = name.get().clone().unwrap_or("Loading...".to_string());
-///
-///     render!(
-///         p { "{name}" }
-///     )
-/// }
-///
-/// #[component]
-/// fn App() -> Element {
-///     render!(Profile { id: 0 })
-/// }
-/// ```
-pub fn use_effect<T, R, D>(, dependencies: D, future: impl FnOnce(D::Out) -> R)
-where
-    D: UseFutureDep,
-    R: UseEffectReturn<T>,
-{
-    struct UseEffect {
-        needs_regen: bool,
-        task: Cell<Option<Task>>,
-        dependencies: Vec<Box<dyn Any>>,
-        cleanup: UseEffectCleanup,
-    }
-
-    impl Drop for UseEffect {
-        fn drop(&mut self) {
-            if let Some(cleanup) = self.cleanup.borrow_mut().take() {
-                cleanup();
-            }
-        }
-    }
-
-    let state = cx.use_hook(move || UseEffect {
-        needs_regen: true,
-        task: Cell::new(None),
-        dependencies: Vec::new(),
-        cleanup: Rc::new(RefCell::new(None)),
-    });
-
-    if dependencies.clone().apply(&mut state.dependencies) || state.needs_regen {
-        // Call the cleanup function if it exists
-        if let Some(cleanup) = state.cleanup.borrow_mut().take() {
-            cleanup();
-        }
-
-        // We don't need regen anymore
-        state.needs_regen = false;
-
-        // Create the new future
-        let return_value = future(dependencies.out());
-
-        let task = return_value.apply(state.cleanup.clone(), cx);
-        state.task.set(Some(task));
-    }
-}
-
-type UseEffectCleanup = Rc<RefCell<Option<Box<dyn FnOnce()>>>>;
-
-/// Something that can be returned from a `use_effect` hook.
-pub trait UseEffectReturn<T> {
-    fn apply(self, oncleanup: UseEffectCleanup, ) -> Task;
-}
-
-impl<T> UseEffectReturn<()> for T
-where
-    T: Future<Output = ()> + 'static,
-{
-    fn apply(self, _: UseEffectCleanup, ) -> Task {
-        cx.push_future(self)
-    }
-}
-
-#[doc(hidden)]
-pub struct CleanupFutureMarker;
-impl<T, F> UseEffectReturn<CleanupFutureMarker> for T
-where
-    T: Future<Output = F> + 'static,
-    F: FnOnce() + 'static,
-{
-    fn apply(self, oncleanup: UseEffectCleanup, ) -> Task {
-        cx.push_future(async move {
-            let cleanup = self.await;
-            *oncleanup.borrow_mut() = Some(Box::new(cleanup) as Box<dyn FnOnce()>);
-        })
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[allow(unused)]
-    #[test]
-    fn test_use_future() {
-        use dioxus_core::prelude::*;
-
-        struct MyProps {
-            a: String,
-            b: i32,
-            c: i32,
-            d: i32,
-            e: i32,
-        }
-
-        fn app(cx: Scope<MyProps>) -> Element {
-            // should only ever run once
-            use_effect((), |_| async move {
-                //
-            });
-
-            // runs when a is changed
-            use_effect((&cx.props.a,), |(a,)| async move {
-                //
-            });
-
-            // runs when a or b is changed
-            use_effect((&cx.props.a, &cx.props.b), |(a, b)| async move {
-                //
-            });
-
-            todo!()
-        }
-    }
-}

+ 0 - 92
packages/hooks/src/use_model.rs

@@ -1,92 +0,0 @@
-//! When building complex components, it's occasionally useful to dip into a pure MVC pattern instead of the
-//! React hooks pattern. Hooks are useful to abstract over some reusable logic, but many models are not reusable
-//! in the same way that hooks are.
-//!
-//! In these cases, we provide `use_model` - a convenient way of abstracting over some state and async functions.
-
-use dioxus_core::prelude::ScopeState;
-use std::{
-    cell::{Cell, Ref, RefCell, RefMut},
-    future::Future,
-    marker::PhantomData,
-    pin::Pin,
-    rc::Rc,
-};
-
-pub fn use_model<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) -> UseModel<'a, T> {
-    let inner = cx.use_hook(|| UseModelInner {
-        update_scheduled: Cell::new(false),
-        update_callback: cx.schedule_update(),
-        value: RefCell::new(f()),
-        // tasks: RefCell::new(Vec::new()),
-    });
-
-    inner.update_scheduled.set(false);
-    UseModel { inner }
-}
-
-pub struct UseModel<'a, T> {
-    inner: &'a UseModelInner<T>,
-}
-
-struct UseModelInner<T> {
-    update_scheduled: Cell<bool>,
-    update_callback: Rc<dyn Fn()>,
-    value: RefCell<T>,
-    // tasks: RefCell<Vec<ModelTask>>,
-}
-
-type ModelTask = Pin<Box<dyn Future<Output = ()> + 'static>>;
-
-impl<'a, T: 'static> UseModel<'a, T> {
-    pub fn read(&self) -> Ref<'_, T> {
-        self.inner.value.borrow()
-    }
-    pub fn write(&self) -> RefMut<'_, T> {
-        self.needs_update();
-        self.inner.value.borrow_mut()
-    }
-    /// Allows the ability to write the value without forcing a re-render
-    pub fn write_silent(&self) -> RefMut<'_, T> {
-        self.inner.value.borrow_mut()
-    }
-
-    pub fn needs_update(&self) {
-        if !self.inner.update_scheduled.get() {
-            self.inner.update_scheduled.set(true);
-            (self.inner.update_callback)();
-        }
-    }
-
-    pub fn set(&self, new: T) {
-        *self.inner.value.borrow_mut() = new;
-        self.needs_update();
-    }
-
-    pub fn read_write(&self) -> (Ref<'_, T>, &Self) {
-        (self.read(), self)
-    }
-
-    pub fn start(&self, _f: impl FnOnce() -> ModelTask) {
-        todo!()
-    }
-}
-
-// keep a coroutine going
-pub fn use_model_coroutine<'a, T, F: Future<Output = ()> + 'static>(
-    cx: &'a ScopeState,
-    _model: UseModel<T>,
-    _f: impl FnOnce(AppModels) -> F,
-) -> UseModelCoroutine {
-    cx.use_hook(|| UseModelTaskInner {
-        task: Default::default(),
-    });
-    todo!()
-}
-
-impl<T> Copy for UseModel<'_, T> {}
-impl<'a, T> Clone for UseModel<'a, T> {
-    fn clone(&self) -> Self {
-        Self { inner: self.inner }
-    }
-}

+ 0 - 252
packages/hooks/src/use_ref.rs

@@ -1,252 +0,0 @@
-use dioxus_core::ScopeState;
-use std::{
-    cell::{Cell, Ref, RefCell, RefMut},
-    rc::Rc,
-    sync::Arc,
-};
-
-/// `use_ref` is a key foundational hook for storing state in Dioxus.
-///
-/// It is different that `use_state` in that the value stored is not "immutable".
-/// Instead, UseRef is designed to store larger values that will be mutated at will.
-///
-/// ## Writing Values
-///
-/// Generally, `use_ref` is just a wrapper around a RefCell that tracks mutable
-/// writes through the `write` method. Whenever `write` is called, the component
-/// that initialized the hook will be marked as "dirty".
-///
-/// ```rust, no_run
-/// let val = use_signal(|| HashMap::<u32, String>::new());
-///
-/// // using `write` will give us a `RefMut` to the inner value, which we can call methods on
-/// // This marks the component as "dirty"
-/// val.write().insert(1, "hello".to_string());
-/// ```
-///
-/// You can avoid this default behavior with `write_silent`
-///
-/// ```rust, no_run
-/// // with `write_silent`, the component will not be re-rendered
-/// val.write_silent().insert(2, "goodbye".to_string());
-/// ```
-///
-/// ## Reading Values
-///
-/// To read values out of the refcell, you can use the `read` method which will retrun a `Ref`.
-///
-/// ```rust, no_run
-/// let map: Ref<_> = val.read();
-///
-/// let item = map.get(&1);
-/// ```
-///
-/// To get an &T out of the RefCell, you need to "reborrow" through the Ref:
-///
-/// ```rust, no_run
-/// let read = val.read();
-/// let map = &*read;
-/// ```
-///
-/// ## Collections and iteration
-///
-/// A common usecase for `use_ref` is to store a large amount of data in a component.
-/// Typically this will be a collection like a HashMap or a Vec. To create new
-/// elements from the collection, we can use `read()` directly in our rsx!.
-///
-/// ```rust, no_run
-/// rsx!{
-///     val.read().iter().map(|(k, v)| {
-///         rsx!{ key: "{k}", "{v}" }
-///     })
-/// }
-/// ```
-///
-/// If you are generating elements outside of `rsx!` then you might need to call
-/// "render" inside the iterator. For some cases you might need to collect into
-/// a temporary Vec.
-///
-/// ```rust, no_run
-/// let items = val.read().iter().map(|(k, v)| {
-///     rsx!{ key: "{k}", "{v}" })
-/// });
-///
-/// // collect into a Vec
-///
-/// let items: Vec<Element> = items.collect();
-/// ```
-///
-/// ## Use in Async
-///
-/// To access values from a `UseRef` in an async context, you need to detach it
-/// from the current scope's lifetime, making it a `'static` value. This is done
-/// by simply calling `to_owned` or `clone`.
-///
-/// ```rust, no_run
-/// let val = use_signal(|| HashMap::<u32, String>::new());
-///
-/// cx.spawn({
-///     let val = val.clone();
-///     async move {
-///         some_work().await;
-///         val.write().insert(1, "hello".to_string());
-///     }
-/// })
-/// ```
-///
-/// If you're working with lots of values like UseState and UseRef, you can use the
-/// `to_owned!` macro to make it easier to write the above code.
-///
-/// ```rust, no_run
-/// let val1 = use_signal(|| HashMap::<u32, String>::new());
-/// let val2 = use_signal(|| HashMap::<u32, String>::new());
-/// let val3 = use_signal(|| HashMap::<u32, String>::new());
-///
-/// cx.spawn({
-///     to_owned![val1, val2, val3];
-///     async move {
-///         some_work().await;
-///         val.write().insert(1, "hello".to_string());
-///     }
-/// })
-/// ```
-#[must_use]
-pub fn use_ref<T: 'static>(nitialize_refcell: impl FnOnce() -> T) -> Signal<T> {
-    let hook = cx.use_hook(|| UseRef {
-        update: cx.schedule_update(),
-        value: Rc::new(RefCell::new(initialize_refcell())),
-        dirty: Rc::new(Cell::new(false)),
-        gen: 0,
-    });
-
-    if hook.dirty.get() {
-        hook.gen += 1;
-        hook.dirty.set(false);
-    }
-
-    hook
-}
-
-/// A type created by the [`use_ref`] hook. See its documentation for more details.
-pub struct UseRef<T> {
-    update: Arc<dyn Fn()>,
-    value: Rc<RefCell<T>>,
-    dirty: Rc<Cell<bool>>,
-    gen: usize,
-}
-
-impl<T> Clone for UseRef<T> {
-    fn clone(&self) -> Self {
-        Self {
-            update: self.update.clone(),
-            value: self.value.clone(),
-            dirty: self.dirty.clone(),
-            gen: self.gen,
-        }
-    }
-}
-
-impl<T> UseRef<T> {
-    /// Read the value in the RefCell into a `Ref`. If this method is called
-    /// while other values are still being `read` or `write`, then your app will crash.
-    ///
-    /// Be very careful when working with this method. If you can, consider using
-    /// the `with` and `with_mut` methods instead, choosing to render Elements
-    /// during the read calls.
-    pub fn read(&self) -> Ref<'_, T> {
-        self.value.borrow()
-    }
-
-    /// Mutably unlock the value in the RefCell. This will mark the component as "dirty"
-    ///
-    /// Uses to `write` should be as short as possible.
-    ///
-    /// Be very careful when working with this method. If you can, consider using
-    /// the `with` and `with_mut` methods instead, choosing to render Elements
-    /// during the read and write calls.
-    pub fn write(&self) -> RefMut<'_, T> {
-        self.needs_update();
-        self.value.borrow_mut()
-    }
-
-    /// Set the curernt value to `new_value`. This will mark the component as "dirty"
-    ///
-    /// This change will propagate immediately, so any other contexts that are
-    /// using this RefCell will also be affected. If called during an async context,
-    /// the component will not be re-rendered until the next `.await` call.
-    pub fn set(&self, new: T) {
-        *self.value.borrow_mut() = new;
-        self.needs_update();
-    }
-
-    /// Mutably unlock the value in the RefCell. This will not mark the component as dirty.
-    /// This is useful if you want to do some work without causing the component to re-render.
-    ///
-    /// Uses to `write` should be as short as possible.
-    ///
-    /// Be very careful when working with this method. If you can, consider using
-    /// the `with` and `with_mut` methods instead, choosing to render Elements
-    pub fn write_silent(&self) -> RefMut<'_, T> {
-        self.value.borrow_mut()
-    }
-
-    /// Take a reference to the inner value termporarily and produce a new value
-    ///
-    /// Note: You can always "reborrow" the value through the RefCell.
-    /// This method just does it for you automatically.
-    ///
-    /// ```rust, no_run
-    /// let val = use_signal(|| HashMap::<u32, String>::new());
-    ///
-    ///
-    /// // use reborrowing
-    /// let inner = &*val.read();
-    ///
-    /// // or, be safer and use `with`
-    /// val.with(|i| println!("{:?}", i));
-    /// ```
-    pub fn with<O>(&self, immutable_callback: impl FnOnce(&T) -> O) -> O {
-        immutable_callback(&*self.read())
-    }
-
-    /// Take a reference to the inner value termporarily and produce a new value,
-    /// modifying the original in place.
-    ///
-    /// Note: You can always "reborrow" the value through the RefCell.
-    /// This method just does it for you automatically.
-    ///
-    /// ```rust, no_run
-    /// let val = use_signal(|| HashMap::<u32, String>::new());
-    ///
-    ///
-    /// // use reborrowing
-    /// let inner = &mut *val.write();
-    ///
-    /// // or, be safer and use `with`
-    /// val.with_mut(|i| i.insert(1, "hi"));
-    /// ```
-    pub fn with_mut<O>(&self, mutable_callback: impl FnOnce(&mut T) -> O) -> O {
-        mutable_callback(&mut *self.write())
-    }
-
-    /// Call the inner callback to mark the originator component as dirty.
-    ///
-    /// This will cause the component to be re-rendered after the current scope
-    /// has ended or the current async task has been yielded through await.
-    pub fn needs_update(&self) {
-        self.dirty.set(true);
-        (self.update)();
-    }
-}
-
-// UseRef memoizes not on value but on cell
-// Memoizes on "generation" - so it will cause a re-render if the value changes
-impl<T> PartialEq for UseRef<T> {
-    fn eq(&self, other: &Self) -> bool {
-        if Rc::ptr_eq(&self.value, &other.value) {
-            self.gen == other.gen
-        } else {
-            false
-        }
-    }
-}

+ 0 - 0
packages/hooks/src/use_signal.rs


+ 0 - 524
packages/hooks/src/use_state.rs

@@ -1,524 +0,0 @@
-#![warn(clippy::pedantic)]
-
-use dioxus_core::prelude::*;
-use std::{
-    cell::{RefCell, RefMut},
-    fmt::{Debug, Display},
-    ops::{Add, Div, Mul, Not, Sub},
-    rc::Rc,
-    sync::Arc,
-};
-
-/// Store state between component renders.
-///
-/// ## Dioxus equivalent of useState, designed for Rust
-///
-/// The Dioxus version of `useState` for state management inside components. It allows you to ergonomically store and
-/// modify state between component renders. When the state is updated, the component will re-render.
-///
-///
-/// ```ignore
-/// const Example: Component = |cx| {
-///     let count = use_signal(|| 0);
-///
-///     rsx! {
-///         div {
-///             h1 { "Count: {count}" }
-///             button { onclick: move |_| *count.modify() += 1, "Increment" }
-///             button { onclick: move |_| *count.modify() -= 1, "Decrement" }
-///         }
-///     ))
-/// }
-/// ```
-#[must_use]
-pub fn use_state<T: 'static>
-    initial_state_fn: impl FnOnce() -> T,
-) -> &UseState<T> {
-    let hook = cx.use_hook(move || {
-        let current_val = Rc::new(initial_state_fn());
-        let update_callback = cx.schedule_update();
-        let slot = Rc::new(RefCell::new(current_val.clone()));
-        let setter = Rc::new({
-            to_owned![update_callback, slot];
-            move |new| {
-                {
-                    let mut slot = slot.borrow_mut();
-
-                    // if there's only one reference (weak or otherwise), we can just swap the values
-                    // Typically happens when the state is set multiple times - we don't want to create a new Rc for each new value
-                    if let Some(val) = Rc::get_mut(&mut slot) {
-                        *val = new;
-                    } else {
-                        *slot = Rc::new(new);
-                    }
-                }
-                update_callback();
-            }
-        });
-
-        UseState {
-            current_val,
-            update_callback,
-            setter,
-            slot,
-        }
-    });
-
-    hook.current_val = hook.slot.borrow().clone();
-
-    hook
-}
-
-pub struct UseState<T: 'static> {
-    pub(crate) current_val: Rc<T>,
-    pub(crate) update_callback: Arc<dyn Fn()>,
-    pub(crate) setter: Rc<dyn Fn(T)>,
-    pub(crate) slot: Rc<RefCell<Rc<T>>>,
-}
-
-impl<T: 'static> UseState<T> {
-    /// Set the state to a new value.
-    pub fn set(&self, new: T) {
-        (self.setter)(new);
-    }
-
-    /// Get the current value of the state by cloning its container Rc.
-    ///
-    /// This is useful when you are dealing with state in async contexts but need
-    /// to know the current value. You are not given a reference to the state.
-    ///
-    /// # Examples
-    /// An async context might need to know the current value:
-    ///
-    /// ```rust, ignore
-    /// fn component() -> Element {
-    ///     let count = use_signal(|| 0);
-    ///     cx.spawn({
-    ///         let set_count = count.to_owned();
-    ///         async move {
-    ///             let current = set_count.current();
-    ///         }
-    ///     })
-    /// }
-    /// ```
-    #[must_use]
-    pub fn current(&self) -> Rc<T> {
-        self.slot.borrow().clone()
-    }
-
-    /// Get the `setter` function directly without the `UseState` wrapper.
-    ///
-    /// This is useful for passing the setter function to other components.
-    ///
-    /// However, for most cases, calling `to_owned` on the state is the
-    /// preferred way to get "another" state handle.
-    ///
-    ///
-    /// # Examples
-    /// A component might require an `Rc<dyn Fn(T)>` as an input to set a value.
-    ///
-    /// ```rust, ignore
-    /// fn component() -> Element {
-    ///     let value = use_signal(|| 0);
-    ///
-    ///     rsx!{
-    ///         Component {
-    ///             handler: value.setter()
-    ///         }
-    ///     }
-    /// }
-    /// ```
-    #[must_use]
-    pub fn setter(&self) -> Rc<dyn Fn(T)> {
-        self.setter.clone()
-    }
-
-    /// Set the state to a new value, using the current state value as a reference.
-    ///
-    /// This is similar to passing a closure to React's `set_value` function.
-    ///
-    /// # Examples
-    ///
-    /// Basic usage:
-    /// ```rust, ignore
-    /// # use dioxus_core::prelude::*;
-    /// # use dioxus_hooks::*;
-    /// fn component() -> Element {
-    ///     let value = use_signal(|| 0);
-    ///
-    ///     // to increment the value
-    ///     value.modify(|v| v + 1);
-    ///
-    ///     // usage in async
-    ///     cx.spawn({
-    ///         let value = value.to_owned();
-    ///         async move {
-    ///             value.modify(|v| v + 1);
-    ///         }
-    ///     });
-    ///
-    ///     # todo!()
-    /// }
-    /// ```
-    pub fn modify(&self, f: impl FnOnce(&T) -> T) {
-        let new_val = {
-            let current = self.slot.borrow();
-            f(current.as_ref())
-        };
-        (self.setter)(new_val);
-    }
-
-    /// Get the value of the state when this handle was created.
-    ///
-    /// This method is useful when you want an `Rc` around the data to cheaply
-    /// pass it around your app.
-    ///
-    /// ## Warning
-    ///
-    /// This will return a stale value if used within async contexts.
-    ///
-    /// Try `current` to get the real current value of the state.
-    ///
-    /// ## Example
-    ///
-    /// ```rust, ignore
-    /// # use dioxus_core::prelude::*;
-    /// # use dioxus_hooks::*;
-    /// fn component() -> Element {
-    ///     let value = use_signal(|| 0);
-    ///
-    ///     let as_rc = value.get();
-    ///     assert_eq!(as_rc.as_ref(), &0);
-    ///
-    ///     # todo!()
-    /// }
-    /// ```
-    #[must_use]
-    pub fn get(&self) -> &T {
-        &self.current_val
-    }
-
-    #[must_use]
-    pub fn get_rc(&self) -> &Rc<T> {
-        &self.current_val
-    }
-
-    /// Mark the component that create this [`UseState`] as dirty, forcing it to re-render.
-    ///
-    /// ```rust, ignore
-    /// fn component() -> Element {
-    ///     let count = use_signal(|| 0);
-    ///     cx.spawn({
-    ///         let count = count.to_owned();
-    ///         async move {
-    ///             // for the component to re-render
-    ///             count.needs_update();
-    ///         }
-    ///     })
-    /// }
-    /// ```
-    pub fn needs_update(&self) {
-        (self.update_callback)();
-    }
-}
-
-impl<T: Clone> UseState<T> {
-    /// Get a mutable handle to the value by calling `ToOwned::to_owned` on the
-    /// current value.
-    ///
-    /// This is essentially cloning the underlying value and then setting it,
-    /// giving you a mutable handle in the process. This method is intended for
-    /// types that are cheaply cloneable.
-    ///
-    /// If you are comfortable dealing with `RefMut`, then you can use `make_mut` to get
-    /// the underlying slot. However, be careful with `RefMut` since you might panic
-    /// if the `RefCell` is left open.
-    ///
-    /// # Examples
-    ///
-    /// ```rust, ignore
-    /// let val = use_signal(|| 0);
-    ///
-    /// val.with_mut(|v| *v = 1);
-    /// ```
-    pub fn with_mut(&self, apply: impl FnOnce(&mut T)) {
-        let mut slot = self.slot.borrow_mut();
-        let mut inner = slot.as_ref().to_owned();
-
-        apply(&mut inner);
-
-        if let Some(new) = Rc::get_mut(&mut slot) {
-            *new = inner;
-        } else {
-            *slot = Rc::new(inner);
-        }
-
-        self.needs_update();
-    }
-
-    /// Get a mutable handle to the value by calling `ToOwned::to_owned` on the
-    /// current value.
-    ///
-    /// This is essentially cloning the underlying value and then setting it,
-    /// giving you a mutable handle in the process. This method is intended for
-    /// types that are cheaply cloneable.
-    ///
-    /// # Warning
-    /// Be careful with `RefMut` since you might panic if the `RefCell` is left open!
-    ///
-    /// # Examples
-    ///
-    /// ```rust, ignore
-    /// let val = use_signal(|| 0);
-    ///
-    /// *val.make_mut() += 1;
-    /// ```
-    #[must_use]
-    #[allow(clippy::missing_panics_doc)]
-    pub fn make_mut(&self) -> RefMut<T> {
-        let mut slot = self.slot.borrow_mut();
-
-        self.needs_update();
-
-        if Rc::strong_count(&*slot) > 0 {
-            *slot = Rc::new(slot.as_ref().to_owned());
-        }
-
-        RefMut::map(slot, |rc| Rc::get_mut(rc).expect("the hard count to be 0"))
-    }
-
-    /// Convert this handle to a tuple of the value and the handle itself.
-    #[must_use]
-    pub fn split(&self) -> (&T, &Self) {
-        (&self.current_val, self)
-    }
-}
-
-impl<T: 'static> Clone for UseState<T> {
-    fn clone(&self) -> Self {
-        UseState {
-            current_val: self.current_val.clone(),
-            update_callback: self.update_callback.clone(),
-            setter: self.setter.clone(),
-            slot: self.slot.clone(),
-        }
-    }
-}
-
-impl<T: 'static + Display> std::fmt::Display for UseState<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.current_val)
-    }
-}
-
-impl<T: std::fmt::Binary> std::fmt::Binary for UseState<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{:b}", self.current_val.as_ref())
-    }
-}
-
-impl<T: PartialEq> PartialEq<T> for UseState<T> {
-    fn eq(&self, other: &T) -> bool {
-        self.current_val.as_ref() == other
-    }
-}
-
-// todo: this but for more interesting conrete types
-impl PartialEq<bool> for &UseState<bool> {
-    fn eq(&self, other: &bool) -> bool {
-        self.current_val.as_ref() == other
-    }
-}
-
-impl<T> PartialEq<UseState<T>> for UseState<T> {
-    fn eq(&self, other: &UseState<T>) -> bool {
-        Rc::ptr_eq(&self.current_val, &other.current_val)
-    }
-}
-
-impl<T: std::cmp::PartialOrd> PartialOrd<T> for UseState<T> {
-    fn ge(&self, other: &T) -> bool {
-        *self.current_val >= *other
-    }
-
-    fn gt(&self, other: &T) -> bool {
-        *self.current_val > *other
-    }
-
-    fn le(&self, other: &T) -> bool {
-        *self.current_val <= *other
-    }
-
-    fn lt(&self, other: &T) -> bool {
-        *self.current_val < *other
-    }
-
-    fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
-        (*self.current_val).partial_cmp(other)
-    }
-}
-
-impl<T: std::cmp::PartialOrd> PartialOrd<UseState<T>> for UseState<T> {
-    fn ge(&self, other: &UseState<T>) -> bool {
-        self.current_val >= other.current_val
-    }
-
-    fn gt(&self, other: &UseState<T>) -> bool {
-        self.current_val > other.current_val
-    }
-
-    fn le(&self, other: &UseState<T>) -> bool {
-        self.current_val <= other.current_val
-    }
-
-    fn lt(&self, other: &UseState<T>) -> bool {
-        self.current_val < other.current_val
-    }
-
-    fn partial_cmp(&self, other: &UseState<T>) -> Option<std::cmp::Ordering> {
-        self.current_val.partial_cmp(&other.current_val)
-    }
-}
-
-impl<T: Debug> Debug for UseState<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{:?}", self.current_val)
-    }
-}
-
-impl<T> std::ops::Deref for UseState<T> {
-    type Target = T;
-
-    fn deref(&self) -> &Self::Target {
-        self.current_val.as_ref()
-    }
-}
-
-impl<T: Not + Copy> std::ops::Not for &UseState<T> {
-    type Output = <T as std::ops::Not>::Output;
-
-    fn not(self) -> Self::Output {
-        self.current_val.not()
-    }
-}
-
-impl<T: Not + Copy> std::ops::Not for UseState<T> {
-    type Output = <T as std::ops::Not>::Output;
-
-    fn not(self) -> Self::Output {
-        self.current_val.not()
-    }
-}
-
-impl<T: std::ops::Add + Copy> std::ops::Add<T> for &UseState<T> {
-    type Output = <T as std::ops::Add>::Output;
-
-    fn add(self, other: T) -> Self::Output {
-        *self.current_val.as_ref() + other
-    }
-}
-impl<T: std::ops::Sub + Copy> std::ops::Sub<T> for &UseState<T> {
-    type Output = <T as std::ops::Sub>::Output;
-
-    fn sub(self, other: T) -> Self::Output {
-        *self.current_val.as_ref() - other
-    }
-}
-
-impl<T: std::ops::Div + Copy> std::ops::Div<T> for &UseState<T> {
-    type Output = <T as std::ops::Div>::Output;
-
-    fn div(self, other: T) -> Self::Output {
-        *self.current_val.as_ref() / other
-    }
-}
-
-impl<T: std::ops::Mul + Copy> std::ops::Mul<T> for &UseState<T> {
-    type Output = <T as std::ops::Mul>::Output;
-
-    fn mul(self, other: T) -> Self::Output {
-        *self.current_val.as_ref() * other
-    }
-}
-
-impl<T: Add<Output = T> + Copy> std::ops::AddAssign<T> for &UseState<T> {
-    fn add_assign(&mut self, rhs: T) {
-        self.set((*self.current()) + rhs);
-    }
-}
-
-impl<T: Sub<Output = T> + Copy> std::ops::SubAssign<T> for &UseState<T> {
-    fn sub_assign(&mut self, rhs: T) {
-        self.set((*self.current()) - rhs);
-    }
-}
-
-impl<T: Mul<Output = T> + Copy> std::ops::MulAssign<T> for &UseState<T> {
-    fn mul_assign(&mut self, rhs: T) {
-        self.set((*self.current()) * rhs);
-    }
-}
-
-impl<T: Div<Output = T> + Copy> std::ops::DivAssign<T> for &UseState<T> {
-    fn div_assign(&mut self, rhs: T) {
-        self.set((*self.current()) / rhs);
-    }
-}
-
-impl<T: Add<Output = T> + Copy> std::ops::AddAssign<T> for UseState<T> {
-    fn add_assign(&mut self, rhs: T) {
-        self.set((*self.current()) + rhs);
-    }
-}
-
-impl<T: Sub<Output = T> + Copy> std::ops::SubAssign<T> for UseState<T> {
-    fn sub_assign(&mut self, rhs: T) {
-        self.set((*self.current()) - rhs);
-    }
-}
-
-impl<T: Mul<Output = T> + Copy> std::ops::MulAssign<T> for UseState<T> {
-    fn mul_assign(&mut self, rhs: T) {
-        self.set((*self.current()) * rhs);
-    }
-}
-
-impl<T: Div<Output = T> + Copy> std::ops::DivAssign<T> for UseState<T> {
-    fn div_assign(&mut self, rhs: T) {
-        self.set((*self.current()) / rhs);
-    }
-}
-
-#[test]
-fn api_makes_sense() {
-    #[allow(unused)]
-    fn app() -> Element {
-        let val = use_signal(|| 0);
-
-        val.set(0);
-        val.modify(|v| v + 1);
-        let real_current = val.current();
-
-        match val.get() {
-            10 => {
-                val.set(20);
-                val.modify(|v| v + 1);
-            }
-            20 => {}
-            _ => {
-                println!("{real_current}");
-            }
-        }
-
-        cx.spawn({
-            to_owned![val];
-            async move {
-                val.modify(|f| f + 1);
-            }
-        });
-
-        // cx.render(LazyNodes::new(|f| f.static_text("asd")))
-
-        todo!()
-    }
-}