diff --git a/examples/borrowed.rs b/examples/borrowed.rs index d5e06197c..7de2ff80d 100644 --- a/examples/borrowed.rs +++ b/examples/borrowed.rs @@ -23,7 +23,7 @@ fn main() { } fn app(cx: Scope) -> Element { - let text = cx.use_hook(|_| vec![String::from("abc=def")]); + let text = cx.use_hook(|| vec![String::from("abc=def")]); let first = text.get_mut(0).unwrap(); diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 10bd0569a..582785003 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -658,7 +658,7 @@ impl ScopeState { /// struct SharedState(&'static str); /// /// static App: Component = |cx| { - /// cx.use_hook(|_| cx.provide_context(SharedState("world"))); + /// cx.use_hook(|| cx.provide_context(SharedState("world"))); /// rsx!(cx, Child {}) /// } /// @@ -684,7 +684,7 @@ impl ScopeState { /// struct SharedState(&'static str); /// /// static App: Component = |cx| { - /// cx.use_hook(|_| cx.provide_root_context(SharedState("world"))); + /// cx.use_hook(|| cx.provide_root_context(SharedState("world"))); /// rsx!(cx, Child {}) /// } /// @@ -811,33 +811,31 @@ impl ScopeState { })) } - /// Store a value between renders + /// Store a value between renders. The foundational hook for all other hooks. /// - /// This is *the* foundational hook for all other hooks. + /// Accepts an `initializer` closure, which is run on the first use of the hook (typically the initial render). The return value of this closure is stored for the lifetime of the component, and a mutable reference to it is provided on every render as the return value of `use_hook`. /// - /// - Initializer: closure used to create the initial hook state - /// - Runner: closure used to output a value every time the hook is used - /// - /// To "cleanup" the hook, implement `Drop` on the stored hook value. Whenever the component is dropped, the hook - /// will be dropped as well. + /// When the component is unmounted (removed from the UI), the value is dropped. This means you can return a custom type and provide cleanup code by implementing the [`Drop`] trait /// /// # Example /// - /// ```ignore - /// // use_ref is the simplest way of storing a value between renders - /// fn use_ref(initial_value: impl FnOnce() -> T) -> &RefCell { - /// use_hook(|| Rc::new(RefCell::new(initial_value()))) + /// ``` + /// use dioxus_core::ScopeState; + /// + /// // prints a greeting on the initial render + /// pub fn use_hello_world(cx: &ScopeState) { + /// cx.use_hook(|| println!("Hello, world!")); /// } /// ``` #[allow(clippy::mut_from_ref)] - pub fn use_hook(&self, initializer: impl FnOnce(usize) -> State) -> &mut State { + pub fn use_hook(&self, initializer: impl FnOnce() -> State) -> &mut State { let mut vals = self.hook_vals.borrow_mut(); let hook_len = vals.len(); let cur_idx = self.hook_idx.get(); if cur_idx >= hook_len { - vals.push(self.hook_arena.alloc(initializer(hook_len))); + vals.push(self.hook_arena.alloc(initializer())); } vals diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 67a201f9f..df6de3092 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -10,7 +10,7 @@ pub type ProxyType = EventLoopProxy; /// Get an imperative handle to the current window pub fn use_window(cx: &ScopeState) -> &DesktopContext { - cx.use_hook(|_| cx.consume_context::()) + cx.use_hook(|| cx.consume_context::()) .as_ref() .unwrap() } @@ -232,5 +232,5 @@ pub(super) fn handler( pub fn use_eval(cx: &ScopeState) -> &dyn Fn(S) { let desktop = use_window(cx).clone(); - cx.use_hook(|_| move |script| desktop.eval(script)) + cx.use_hook(|| move |script| desktop.eval(script)) } diff --git a/packages/dioxus/tests/borrowedstate.rs b/packages/dioxus/tests/borrowedstate.rs index e65456f0b..520cce8a6 100644 --- a/packages/dioxus/tests/borrowedstate.rs +++ b/packages/dioxus/tests/borrowedstate.rs @@ -8,7 +8,7 @@ fn test_borrowed_state() { } fn Parent(cx: Scope) -> Element { - let value = cx.use_hook(|_| String::new()); + let value = cx.use_hook(|| String::new()); cx.render(rsx! { div { diff --git a/packages/dioxus/tests/earlyabort.rs b/packages/dioxus/tests/earlyabort.rs index 3de5e2f9c..e996b3d4c 100644 --- a/packages/dioxus/tests/earlyabort.rs +++ b/packages/dioxus/tests/earlyabort.rs @@ -20,7 +20,7 @@ fn new_dom(app: Component

, props: P) -> VirtualDom { #[test] fn test_early_abort() { const app: Component = |cx| { - let val = cx.use_hook(|_| 0); + let val = cx.use_hook(|| 0); *val += 1; diff --git a/packages/dioxus/tests/lifecycle.rs b/packages/dioxus/tests/lifecycle.rs index 6f85954ea..237938d36 100644 --- a/packages/dioxus/tests/lifecycle.rs +++ b/packages/dioxus/tests/lifecycle.rs @@ -34,7 +34,7 @@ fn manual_diffing() { #[test] fn events_generate() { fn app(cx: Scope) -> Element { - let count = cx.use_hook(|_| 0); + let count = cx.use_hook(|| 0); let inner = match *count { 0 => { @@ -77,7 +77,7 @@ fn events_generate() { #[test] fn components_generate() { fn app(cx: Scope) -> Element { - let render_phase = cx.use_hook(|_| 0); + let render_phase = cx.use_hook(|| 0); *render_phase += 1; cx.render(match *render_phase { @@ -171,7 +171,7 @@ fn components_generate() { #[test] fn component_swap() { fn app(cx: Scope) -> Element { - let render_phase = cx.use_hook(|_| 0); + let render_phase = cx.use_hook(|| 0); *render_phase += 1; cx.render(match *render_phase { diff --git a/packages/dioxus/tests/miri_stress.rs b/packages/dioxus/tests/miri_stress.rs index 329e62f9b..c91c5a005 100644 --- a/packages/dioxus/tests/miri_stress.rs +++ b/packages/dioxus/tests/miri_stress.rs @@ -22,7 +22,7 @@ fn new_dom(app: Component

, props: P) -> VirtualDom { #[test] fn test_memory_leak() { fn app(cx: Scope) -> Element { - let val = cx.use_hook(|_| 0); + let val = cx.use_hook(|| 0); *val += 1; @@ -30,7 +30,7 @@ fn test_memory_leak() { return None; } - let name = cx.use_hook(|_| String::from("asd")); + let name = cx.use_hook(|| String::from("asd")); cx.render(rsx!( div { "Hello, world!" } @@ -79,7 +79,7 @@ fn test_memory_leak() { #[test] fn memo_works_properly() { fn app(cx: Scope) -> Element { - let val = cx.use_hook(|_| 0); + let val = cx.use_hook(|| 0); *val += 1; @@ -87,7 +87,7 @@ fn memo_works_properly() { return None; } - let name = cx.use_hook(|_| String::from("asd")); + let name = cx.use_hook(|| String::from("asd")); cx.render(rsx!( div { "Hello, world! {name}" } @@ -192,7 +192,7 @@ fn free_works_on_root_hooks() { } fn app(cx: Scope) -> Element { - let name = cx.use_hook(|_| Droppable(String::from("asd"))); + let name = cx.use_hook(|| Droppable(String::from("asd"))); rsx!(cx, div { "{name.0}" }) } @@ -204,7 +204,7 @@ fn free_works_on_root_hooks() { fn old_props_arent_stale() { fn app(cx: Scope) -> Element { dbg!("rendering parent"); - let cnt = cx.use_hook(|_| 0); + let cnt = cx.use_hook(|| 0); *cnt += 1; if *cnt == 1 { diff --git a/packages/dioxus/tests/sharedstate.rs b/packages/dioxus/tests/sharedstate.rs index f3b6fabf3..85432ad4c 100644 --- a/packages/dioxus/tests/sharedstate.rs +++ b/packages/dioxus/tests/sharedstate.rs @@ -36,7 +36,7 @@ fn swap_test() { struct MySharedState(&'static str); fn app(cx: Scope) -> Element { - let val = cx.use_hook(|_| 0); + let val = cx.use_hook(|| 0); *val += 1; cx.provide_context(Rc::new(MySharedState("world!"))); diff --git a/packages/fermi/src/hooks/atom_ref.rs b/packages/fermi/src/hooks/atom_ref.rs index 14c98453d..fc7df59fc 100644 --- a/packages/fermi/src/hooks/atom_ref.rs +++ b/packages/fermi/src/hooks/atom_ref.rs @@ -16,7 +16,7 @@ use std::{ pub fn use_atom_ref(cx: &ScopeState, atom: AtomRef) -> &UseAtomRef { let root = use_atom_root(cx); - &cx.use_hook(|_| { + &cx.use_hook(|| { root.initialize(atom); ( UseAtomRef { diff --git a/packages/fermi/src/hooks/atom_root.rs b/packages/fermi/src/hooks/atom_root.rs index 72862a59f..f9eb07bc9 100644 --- a/packages/fermi/src/hooks/atom_root.rs +++ b/packages/fermi/src/hooks/atom_root.rs @@ -4,7 +4,7 @@ use std::rc::Rc; // Returns the atom root, initiaizing it at the root of the app if it does not exist. pub fn use_atom_root(cx: &ScopeState) -> &Rc { - cx.use_hook(|_| match cx.consume_context::>() { + cx.use_hook(|| match cx.consume_context::>() { Some(root) => root, None => cx.provide_root_context(Rc::new(AtomRoot::new(cx.schedule_update_any()))), }) diff --git a/packages/fermi/src/hooks/init_atom_root.rs b/packages/fermi/src/hooks/init_atom_root.rs index 12fa3efca..db04d4e14 100644 --- a/packages/fermi/src/hooks/init_atom_root.rs +++ b/packages/fermi/src/hooks/init_atom_root.rs @@ -4,7 +4,7 @@ use std::rc::Rc; // Initializes the atom root and retuns it; pub fn use_init_atom_root(cx: &ScopeState) -> &Rc { - cx.use_hook(|_| match cx.consume_context::>() { + cx.use_hook(|| match cx.consume_context::>() { Some(ctx) => ctx, None => cx.provide_context(Rc::new(AtomRoot::new(cx.schedule_update_any()))), }) diff --git a/packages/fermi/src/hooks/read.rs b/packages/fermi/src/hooks/read.rs index 9b66d7bc6..57a544e93 100644 --- a/packages/fermi/src/hooks/read.rs +++ b/packages/fermi/src/hooks/read.rs @@ -22,7 +22,7 @@ pub fn use_read_rc(cx: &ScopeState, f: impl Readable) -> &Rc { } } - let inner = cx.use_hook(|_| UseReadInner { + let inner = cx.use_hook(|| UseReadInner { value: None, root: root.clone(), scope_id: cx.scope_id(), diff --git a/packages/fermi/src/hooks/set.rs b/packages/fermi/src/hooks/set.rs index fa1db9129..5e5141227 100644 --- a/packages/fermi/src/hooks/set.rs +++ b/packages/fermi/src/hooks/set.rs @@ -4,7 +4,7 @@ use std::rc::Rc; pub fn use_set(cx: &ScopeState, f: impl Writable) -> &Rc { let root = use_atom_root(cx); - cx.use_hook(|_| { + cx.use_hook(|| { let id = f.unique_id(); let root = root.clone(); root.initialize(f); diff --git a/packages/fermi/src/hooks/state.rs b/packages/fermi/src/hooks/state.rs index 41e4e8ab0..c75446bbe 100644 --- a/packages/fermi/src/hooks/state.rs +++ b/packages/fermi/src/hooks/state.rs @@ -33,7 +33,7 @@ use std::{ pub fn use_atom_state(cx: &ScopeState, f: impl Writable) -> &AtomState { let root = crate::use_atom_root(cx); - let inner = cx.use_hook(|_| AtomState { + let inner = cx.use_hook(|| AtomState { value: None, root: root.clone(), scope_id: cx.scope_id(), diff --git a/packages/hooks/src/use_shared_state.rs b/packages/hooks/src/use_shared_state.rs index 2d9f9eb60..9c4048b0e 100644 --- a/packages/hooks/src/use_shared_state.rs +++ b/packages/hooks/src/use_shared_state.rs @@ -61,7 +61,7 @@ impl ProvidedStateInner { /// /// pub fn use_context(cx: &ScopeState) -> Option> { - let state = cx.use_hook(|_| { + let state = cx.use_hook(|| { let scope_id = cx.scope_id(); let root = cx.consume_context::>(); @@ -173,7 +173,7 @@ where /// /// pub fn use_context_provider(cx: &ScopeState, f: impl FnOnce() -> T) { - cx.use_hook(|_| { + cx.use_hook(|| { let state: ProvidedState = Rc::new(RefCell::new(ProvidedStateInner { value: Rc::new(RefCell::new(f())), notify_any: cx.schedule_update_any(), diff --git a/packages/hooks/src/usecoroutine.rs b/packages/hooks/src/usecoroutine.rs index 65a3ff52d..503c0e91a 100644 --- a/packages/hooks/src/usecoroutine.rs +++ b/packages/hooks/src/usecoroutine.rs @@ -65,7 +65,7 @@ where G: FnOnce(UnboundedReceiver) -> F, F: Future + 'static, { - cx.use_hook(|_| { + cx.use_hook(|| { let (tx, rx) = futures_channel::mpsc::unbounded(); let task = cx.push_future(init(rx)); cx.provide_context(CoroutineHandle { tx, task }) @@ -76,7 +76,7 @@ where /// /// See the docs for [`use_coroutine`] for more details. pub fn use_coroutine_handle(cx: &ScopeState) -> Option<&CoroutineHandle> { - cx.use_hook(|_| cx.consume_context::>()) + cx.use_hook(|| cx.consume_context::>()) .as_ref() } diff --git a/packages/hooks/src/useeffect.rs b/packages/hooks/src/useeffect.rs index 09366fc35..e82335222 100644 --- a/packages/hooks/src/useeffect.rs +++ b/packages/hooks/src/useeffect.rs @@ -34,7 +34,7 @@ where dependencies: Vec>, } - let state = cx.use_hook(move |_| UseEffect { + let state = cx.use_hook(move || UseEffect { needs_regen: true, task: Cell::new(None), dependencies: Vec::new(), diff --git a/packages/hooks/src/usefuture.rs b/packages/hooks/src/usefuture.rs index d018d1b98..1aa7800ec 100644 --- a/packages/hooks/src/usefuture.rs +++ b/packages/hooks/src/usefuture.rs @@ -25,7 +25,7 @@ where F: Future + 'static, D: UseFutureDep, { - let state = cx.use_hook(move |_| UseFuture { + let state = cx.use_hook(move || UseFuture { update: cx.schedule_update(), needs_regen: Cell::new(true), slot: Rc::new(Cell::new(None)), diff --git a/packages/hooks/src/usemodel.rs b/packages/hooks/src/usemodel.rs index 301774f94..0e81fe3f8 100644 --- a/packages/hooks/src/usemodel.rs +++ b/packages/hooks/src/usemodel.rs @@ -14,7 +14,7 @@ use std::{ }; pub fn use_model<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) -> UseModel<'a, T> { - let inner = cx.use_hook(|_| UseModelInner { + let inner = cx.use_hook(|| UseModelInner { update_scheduled: Cell::new(false), update_callback: cx.schedule_update(), value: RefCell::new(f()), @@ -78,7 +78,7 @@ pub fn use_model_coroutine<'a, T, F: Future + 'static>( _model: UseModel, _f: impl FnOnce(AppModels) -> F, ) -> UseModelCoroutine { - cx.use_hook(|_| UseModelTaskInner { + cx.use_hook(|| UseModelTaskInner { task: Default::default(), }); todo!() diff --git a/packages/hooks/src/useref.rs b/packages/hooks/src/useref.rs index 476ef7d62..da221554c 100644 --- a/packages/hooks/src/useref.rs +++ b/packages/hooks/src/useref.rs @@ -111,7 +111,7 @@ use std::{ /// }) /// ``` pub fn use_ref(cx: &ScopeState, initialize_refcell: impl FnOnce() -> T) -> &UseRef { - let hook = cx.use_hook(|_| UseRef { + let hook = cx.use_hook(|| UseRef { update: cx.schedule_update(), value: Rc::new(RefCell::new(initialize_refcell())), dirty: Rc::new(Cell::new(false)), diff --git a/packages/hooks/src/usestate.rs b/packages/hooks/src/usestate.rs index b2b4e80af..cbf35a889 100644 --- a/packages/hooks/src/usestate.rs +++ b/packages/hooks/src/usestate.rs @@ -34,7 +34,7 @@ pub fn use_state( cx: &ScopeState, initial_state_fn: impl FnOnce() -> T, ) -> &UseState { - let hook = cx.use_hook(move |_| { + 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())); diff --git a/packages/hooks/src/usesuspense.rs b/packages/hooks/src/usesuspense.rs index 834871304..d4405bd88 100644 --- a/packages/hooks/src/usesuspense.rs +++ b/packages/hooks/src/usesuspense.rs @@ -7,7 +7,7 @@ pub fn use_suspense + 'static>( create_future: impl FnOnce() -> F, render: impl FnOnce(&R) -> Element, ) -> Element { - let sus = cx.use_hook(|_| { + let sus = cx.use_hook(|| { let fut = create_future(); let wip_value: Rc>> = Default::default(); diff --git a/packages/router/src/components/link.rs b/packages/router/src/components/link.rs index e742a97d1..1746ba5a9 100644 --- a/packages/router/src/components/link.rs +++ b/packages/router/src/components/link.rs @@ -77,7 +77,7 @@ pub struct LinkProps<'a> { /// } /// ``` pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element { - let svc = cx.use_hook(|_| cx.consume_context::>()); + let svc = cx.use_hook(|| cx.consume_context::>()); let LinkProps { to, diff --git a/packages/router/src/components/redirect.rs b/packages/router/src/components/redirect.rs index 3e3361ab9..561dec7b1 100644 --- a/packages/router/src/components/redirect.rs +++ b/packages/router/src/components/redirect.rs @@ -34,7 +34,7 @@ pub struct RedirectProps<'a> { pub fn Redirect<'a>(cx: Scope<'a, RedirectProps<'a>>) -> Element { let router = use_router(&cx); - let immediate_redirect = cx.use_hook(|_| { + let immediate_redirect = cx.use_hook(|| { if let Some(from) = cx.props.from { router.register_total_route(from.to_string(), cx.scope_id()); false diff --git a/packages/router/src/components/route.rs b/packages/router/src/components/route.rs index 6a80124d5..b613a4d5c 100644 --- a/packages/router/src/components/route.rs +++ b/packages/router/src/components/route.rs @@ -28,10 +28,10 @@ pub struct RouteProps<'a> { /// ``` pub fn Route<'a>(cx: Scope<'a, RouteProps<'a>>) -> Element { let router_root = cx - .use_hook(|_| cx.consume_context::>()) + .use_hook(|| cx.consume_context::>()) .as_ref()?; - cx.use_hook(|_| { + cx.use_hook(|| { // create a bigger, better, longer route if one above us exists let total_route = match cx.consume_context::() { Some(ctx) => ctx.total_route, diff --git a/packages/router/src/components/router.rs b/packages/router/src/components/router.rs index f4e40e79d..f8532ec4f 100644 --- a/packages/router/src/components/router.rs +++ b/packages/router/src/components/router.rs @@ -37,7 +37,7 @@ pub struct RouterProps<'a> { /// Will fallback to HashRouter is BrowserRouter is not available, or through configuration. #[allow(non_snake_case)] pub fn Router<'a>(cx: Scope<'a, RouterProps<'a>>) -> Element { - let svc = cx.use_hook(|_| { + let svc = cx.use_hook(|| { cx.provide_context(RouterCore::new( &cx, RouterCfg { diff --git a/packages/router/src/hooks/use_route.rs b/packages/router/src/hooks/use_route.rs index abb0ea4a5..27f99dfea 100644 --- a/packages/router/src/hooks/use_route.rs +++ b/packages/router/src/hooks/use_route.rs @@ -7,7 +7,7 @@ use url::Url; /// context of a [`Router`]. If this function is called outside of a `Router` /// component it will panic. pub fn use_route(cx: &ScopeState) -> &UseRoute { - let handle = cx.use_hook(|_| { + let handle = cx.use_hook(|| { let router = cx .consume_context::() .expect("Cannot call use_route outside the scope of a Router component"); diff --git a/packages/router/src/hooks/use_router.rs b/packages/router/src/hooks/use_router.rs index 25a9a471f..4b4a12487 100644 --- a/packages/router/src/hooks/use_router.rs +++ b/packages/router/src/hooks/use_router.rs @@ -3,7 +3,7 @@ use dioxus::core::ScopeState; /// This hook provides access to the `RouterService` for the app. pub fn use_router(cx: &ScopeState) -> &RouterService { - cx.use_hook(|_| { + cx.use_hook(|| { cx.consume_context::() .expect("Cannot call use_route outside the scope of a Router component") }) diff --git a/packages/web/src/util.rs b/packages/web/src/util.rs index 3e7232035..772f53608 100644 --- a/packages/web/src/util.rs +++ b/packages/web/src/util.rs @@ -16,7 +16,7 @@ use dioxus_core::*; /// The closure will panic if the provided script is not valid JavaScript code /// or if it returns an uncaught error. pub fn use_eval(cx: &ScopeState) -> &dyn Fn(S) { - cx.use_hook(|_| { + cx.use_hook(|| { |script: S| { js_sys::Function::new_no_args(&script.to_string()) .call0(&wasm_bindgen::JsValue::NULL)