Преглед на файлове

Remove argument from `use_hook` closure (#496)

Also; update docs for said function
Reinis Mazeiks преди 3 години
родител
ревизия
d734dc5b46

+ 1 - 1
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();
 

+ 13 - 15
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<T: 'static>(initial_value: impl FnOnce() -> T) -> &RefCell<T> {
-    ///     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<State: 'static>(&self, initializer: impl FnOnce(usize) -> State) -> &mut State {
+    pub fn use_hook<State: 'static>(&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

+ 2 - 2
packages/desktop/src/desktop_context.rs

@@ -10,7 +10,7 @@ pub type ProxyType = EventLoopProxy<UserWindowEvent>;
 
 /// Get an imperative handle to the current window
 pub fn use_window(cx: &ScopeState) -> &DesktopContext {
-    cx.use_hook(|_| cx.consume_context::<DesktopContext>())
+    cx.use_hook(|| cx.consume_context::<DesktopContext>())
         .as_ref()
         .unwrap()
 }
@@ -232,5 +232,5 @@ pub(super) fn handler(
 pub fn use_eval<S: std::string::ToString>(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))
 }

+ 1 - 1
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 {

+ 1 - 1
packages/dioxus/tests/earlyabort.rs

@@ -20,7 +20,7 @@ fn new_dom<P: 'static + Send>(app: Component<P>, 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;
 

+ 3 - 3
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 {

+ 6 - 6
packages/dioxus/tests/miri_stress.rs

@@ -22,7 +22,7 @@ fn new_dom<P: 'static + Send>(app: Component<P>, 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 {

+ 1 - 1
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!")));

+ 1 - 1
packages/fermi/src/hooks/atom_ref.rs

@@ -16,7 +16,7 @@ use std::{
 pub fn use_atom_ref<T: 'static>(cx: &ScopeState, atom: AtomRef<T>) -> &UseAtomRef<T> {
     let root = use_atom_root(cx);
 
-    &cx.use_hook(|_| {
+    &cx.use_hook(|| {
         root.initialize(atom);
         (
             UseAtomRef {

+ 1 - 1
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<AtomRoot> {
-    cx.use_hook(|_| match cx.consume_context::<Rc<AtomRoot>>() {
+    cx.use_hook(|| match cx.consume_context::<Rc<AtomRoot>>() {
         Some(root) => root,
         None => cx.provide_root_context(Rc::new(AtomRoot::new(cx.schedule_update_any()))),
     })

+ 1 - 1
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<AtomRoot> {
-    cx.use_hook(|_| match cx.consume_context::<Rc<AtomRoot>>() {
+    cx.use_hook(|| match cx.consume_context::<Rc<AtomRoot>>() {
         Some(ctx) => ctx,
         None => cx.provide_context(Rc::new(AtomRoot::new(cx.schedule_update_any()))),
     })

+ 1 - 1
packages/fermi/src/hooks/read.rs

@@ -22,7 +22,7 @@ pub fn use_read_rc<V: 'static>(cx: &ScopeState, f: impl Readable<V>) -> &Rc<V> {
         }
     }
 
-    let inner = cx.use_hook(|_| UseReadInner {
+    let inner = cx.use_hook(|| UseReadInner {
         value: None,
         root: root.clone(),
         scope_id: cx.scope_id(),

+ 1 - 1
packages/fermi/src/hooks/set.rs

@@ -4,7 +4,7 @@ use std::rc::Rc;
 
 pub fn use_set<T: 'static>(cx: &ScopeState, f: impl Writable<T>) -> &Rc<dyn Fn(T)> {
     let root = use_atom_root(cx);
-    cx.use_hook(|_| {
+    cx.use_hook(|| {
         let id = f.unique_id();
         let root = root.clone();
         root.initialize(f);

+ 1 - 1
packages/fermi/src/hooks/state.rs

@@ -33,7 +33,7 @@ use std::{
 pub fn use_atom_state<T: 'static>(cx: &ScopeState, f: impl Writable<T>) -> &AtomState<T> {
     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(),

+ 2 - 2
packages/hooks/src/use_shared_state.rs

@@ -61,7 +61,7 @@ impl<T> ProvidedStateInner<T> {
 ///
 ///
 pub fn use_context<T: 'static>(cx: &ScopeState) -> Option<UseSharedState<T>> {
-    let state = cx.use_hook(|_| {
+    let state = cx.use_hook(|| {
         let scope_id = cx.scope_id();
         let root = cx.consume_context::<ProvidedState<T>>();
 
@@ -173,7 +173,7 @@ where
 ///
 ///
 pub fn use_context_provider<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) {
-    cx.use_hook(|_| {
+    cx.use_hook(|| {
         let state: ProvidedState<T> = Rc::new(RefCell::new(ProvidedStateInner {
             value: Rc::new(RefCell::new(f())),
             notify_any: cx.schedule_update_any(),

+ 2 - 2
packages/hooks/src/usecoroutine.rs

@@ -65,7 +65,7 @@ where
     G: FnOnce(UnboundedReceiver<M>) -> F,
     F: Future<Output = ()> + '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<M: 'static>(cx: &ScopeState) -> Option<&CoroutineHandle<M>> {
-    cx.use_hook(|_| cx.consume_context::<CoroutineHandle<M>>())
+    cx.use_hook(|| cx.consume_context::<CoroutineHandle<M>>())
         .as_ref()
 }
 

+ 1 - 1
packages/hooks/src/useeffect.rs

@@ -34,7 +34,7 @@ where
         dependencies: Vec<Box<dyn Any>>,
     }
 
-    let state = cx.use_hook(move |_| UseEffect {
+    let state = cx.use_hook(move || UseEffect {
         needs_regen: true,
         task: Cell::new(None),
         dependencies: Vec::new(),

+ 1 - 1
packages/hooks/src/usefuture.rs

@@ -25,7 +25,7 @@ where
     F: Future<Output = T> + '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)),

+ 2 - 2
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<Output = ()> + 'static>(
     _model: UseModel<T>,
     _f: impl FnOnce(AppModels) -> F,
 ) -> UseModelCoroutine {
-    cx.use_hook(|_| UseModelTaskInner {
+    cx.use_hook(|| UseModelTaskInner {
         task: Default::default(),
     });
     todo!()

+ 1 - 1
packages/hooks/src/useref.rs

@@ -111,7 +111,7 @@ use std::{
 /// })
 /// ```
 pub fn use_ref<T: 'static>(cx: &ScopeState, initialize_refcell: impl FnOnce() -> T) -> &UseRef<T> {
-    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)),

+ 1 - 1
packages/hooks/src/usestate.rs

@@ -34,7 +34,7 @@ pub fn use_state<T: 'static>(
     cx: &ScopeState,
     initial_state_fn: impl FnOnce() -> T,
 ) -> &UseState<T> {
-    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()));

+ 1 - 1
packages/hooks/src/usesuspense.rs

@@ -7,7 +7,7 @@ pub fn use_suspense<R: 'static, F: Future<Output = R> + '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<Cell<Option<R>>> = Default::default();

+ 1 - 1
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::<Arc<RouterCore>>());
+    let svc = cx.use_hook(|| cx.consume_context::<Arc<RouterCore>>());
 
     let LinkProps {
         to,

+ 1 - 1
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

+ 2 - 2
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::<Arc<RouterCore>>())
+        .use_hook(|| cx.consume_context::<Arc<RouterCore>>())
         .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::<RouteContext>() {
             Some(ctx) => ctx.total_route,

+ 1 - 1
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 {

+ 1 - 1
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::<RouterService>()
             .expect("Cannot call use_route outside the scope of a Router component");

+ 1 - 1
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::<RouterService>()
             .expect("Cannot call use_route outside the scope of a Router component")
     })

+ 1 - 1
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<S: std::string::ToString>(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)