Przeglądaj źródła

Add argument to use_callback (#2774)

Matt Hunzinger 11 miesięcy temu
rodzic
commit
205d8e9070

+ 3 - 3
packages/desktop/src/hooks.rs

@@ -71,13 +71,13 @@ pub fn use_asset_handler(
 /// Get a closure that executes any JavaScript in the WebView context.
 pub fn use_global_shortcut(
     accelerator: impl IntoAccelerator,
-    handler: impl FnMut() + 'static,
+    mut handler: impl FnMut() + 'static,
 ) -> Result<ShortcutHandle, ShortcutRegistryError> {
     // wrap the user's handler in something that will carry the scope/runtime with it
-    let cb = use_callback(handler);
+    let cb = use_callback(move |_| handler());
 
     use_hook_with_cleanup(
-        move || window().create_shortcut(accelerator.accelerator(), move || cb.call()),
+        move || window().create_shortcut(accelerator.accelerator(), move || cb.call(())),
         |handle| {
             if let Ok(handle) = handle {
                 handle.remove();

+ 16 - 15
packages/hooks/src/use_callback.rs

@@ -10,7 +10,7 @@ use dioxus_signals::Writable;
 ///
 /// This API is in flux and might not remain.
 #[doc = include_str!("../docs/rules_of_hooks.md")]
-pub fn use_callback<O>(f: impl FnMut() -> O + 'static) -> UseCallback<O> {
+pub fn use_callback<T, O>(f: impl FnMut(T) -> O + 'static) -> UseCallback<T, O> {
     // Create a copyvalue with no contents
     // This copyvalue is generic over F so that it can be sized properly
     let mut inner = use_hook(|| CopyValue::new(None));
@@ -24,9 +24,10 @@ pub fn use_callback<O>(f: impl FnMut() -> O + 'static) -> UseCallback<O> {
         let rt = Runtime::current().unwrap();
 
         UseCallback {
-            inner: CopyValue::new(Box::new(move || {
+            inner: CopyValue::new(Box::new(move |value| {
                 // run this callback in the context of the scope it was created in.
-                let run_callback = || inner.with_mut(|f: &mut Option<_>| f.as_mut().unwrap()());
+                let run_callback =
+                    || inner.with_mut(|f: &mut Option<_>| f.as_mut().unwrap()(value));
                 rt.on_scope(cur_scope, run_callback)
             })),
         }
@@ -36,17 +37,17 @@ pub fn use_callback<O>(f: impl FnMut() -> O + 'static) -> UseCallback<O> {
 /// This callback is not generic over a return type so you can hold a bunch of callbacks at once
 ///
 /// If you need a callback that returns a value, you can simply wrap the closure you pass in that sets a value in its scope
-pub struct UseCallback<O: 'static + ?Sized> {
-    inner: CopyValue<Box<dyn FnMut() -> O>>,
+pub struct UseCallback<T: 'static, O: 'static + ?Sized> {
+    inner: CopyValue<Box<dyn FnMut(T) -> O>>,
 }
 
-impl<O: 'static + ?Sized> PartialEq for UseCallback<O> {
+impl<T: 'static, O: 'static + ?Sized> PartialEq for UseCallback<T, O> {
     fn eq(&self, other: &Self) -> bool {
         self.inner == other.inner
     }
 }
 
-impl<O: 'static + ?Sized> std::fmt::Debug for UseCallback<O> {
+impl<T: 'static, O: 'static + ?Sized> std::fmt::Debug for UseCallback<T, O> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("UseCallback")
             .field("inner", &self.inner.value())
@@ -54,23 +55,23 @@ impl<O: 'static + ?Sized> std::fmt::Debug for UseCallback<O> {
     }
 }
 
-impl<O: 'static + ?Sized> Clone for UseCallback<O> {
+impl<T: 'static, O: 'static + ?Sized> Clone for UseCallback<T, O> {
     fn clone(&self) -> Self {
         Self { inner: self.inner }
     }
 }
-impl<O: 'static> Copy for UseCallback<O> {}
+impl<T: 'static, O: 'static> Copy for UseCallback<T, O> {}
 
-impl<O> UseCallback<O> {
+impl<T, O> UseCallback<T, O> {
     /// Call the callback
-    pub fn call(&self) -> O {
-        (self.inner.write_unchecked())()
+    pub fn call(&self, value: T) -> O {
+        (self.inner.write_unchecked())(value)
     }
 }
 
 // This makes UseCallback callable like a normal function
-impl<O> std::ops::Deref for UseCallback<O> {
-    type Target = dyn Fn() -> O;
+impl<T, O> std::ops::Deref for UseCallback<T, O> {
+    type Target = dyn Fn(T) -> O;
 
     fn deref(&self) -> &Self::Target {
         use std::mem::MaybeUninit;
@@ -80,7 +81,7 @@ impl<O> std::ops::Deref for UseCallback<O> {
         // First we create a closure that captures something with the Same in memory layout as Self (MaybeUninit<Self>).
         let uninit_callable = MaybeUninit::<Self>::uninit();
         // Then move that value into the closure. We assume that the closure now has a in memory layout of Self.
-        let uninit_closure = move || Self::call(unsafe { &*uninit_callable.as_ptr() });
+        let uninit_closure = move |value| Self::call(unsafe { &*uninit_callable.as_ptr() }, value);
 
         // Check that the size of the closure is the same as the size of Self in case the compiler changed the layout of the closure.
         let size_of_closure = std::mem::size_of_val(&uninit_closure);

+ 3 - 3
packages/hooks/src/use_effect.rs

@@ -8,8 +8,8 @@ use crate::use_callback;
 #[doc = include_str!("../docs/side_effects.md")]
 #[doc = include_str!("../docs/rules_of_hooks.md")]
 #[track_caller]
-pub fn use_effect(callback: impl FnMut() + 'static) -> Effect {
-    let callback = use_callback(callback);
+pub fn use_effect(mut callback: impl FnMut() + 'static) -> Effect {
+    let callback = use_callback(move |_| callback());
 
     let location = std::panic::Location::caller();
 
@@ -31,7 +31,7 @@ pub fn use_effect(callback: impl FnMut() + 'static) -> Effect {
             effect_queued.set(true);
             let effect_queued = effect_queued.clone();
             queue_effect(move || {
-                rc.reset_and_run_in(&*callback);
+                rc.reset_and_run_in(|| callback(()));
                 effect_queued.set(false);
             });
         };

+ 4 - 4
packages/hooks/src/use_future.rs

@@ -48,7 +48,7 @@ where
 {
     let mut state = use_signal(|| UseFutureState::Pending);
 
-    let callback = use_callback(move || {
+    let callback = use_callback(move |_| {
         let fut = future();
         spawn(async move {
             state.set(UseFutureState::Pending);
@@ -58,7 +58,7 @@ where
     });
 
     // Create the task inside a CopyValue so we can reset it in-place later
-    let task = use_hook(|| CopyValue::new(callback.call()));
+    let task = use_hook(|| CopyValue::new(callback(())));
 
     // Early returns in dioxus have consequences for use_memo, use_resource, and use_future, etc
     // We *don't* want futures to be running if the component early returns. It's a rather weird behavior to have
@@ -82,7 +82,7 @@ where
 pub struct UseFuture {
     task: CopyValue<Task>,
     state: Signal<UseFutureState>,
-    callback: UseCallback<Task>,
+    callback: UseCallback<(), Task>,
 }
 
 /// A signal that represents the state of a future
@@ -109,7 +109,7 @@ impl UseFuture {
     /// generates.
     pub fn restart(&mut self) {
         self.task.write().cancel();
-        let new_task = self.callback.call();
+        let new_task = self.callback.call(());
         self.task.set(new_task);
     }
 

+ 3 - 3
packages/hooks/src/use_memo.rs

@@ -6,8 +6,8 @@ use dioxus_signals::{Memo, Signal};
 #[doc = include_str!("../docs/rules_of_hooks.md")]
 #[doc = include_str!("../docs/moving_state_around.md")]
 #[track_caller]
-pub fn use_memo<R: PartialEq>(f: impl FnMut() -> R + 'static) -> Memo<R> {
-    let callback = use_callback(f);
+pub fn use_memo<R: PartialEq>(mut f: impl FnMut() -> R + 'static) -> Memo<R> {
+    let callback = use_callback(move |_| f());
     #[allow(clippy::redundant_closure)]
-    use_hook(|| Signal::memo(move || callback()))
+    use_hook(|| Signal::memo(move || callback(())))
 }

+ 5 - 5
packages/hooks/src/use_resource.rs

@@ -28,7 +28,7 @@ where
         (rc, Rc::new(Cell::new(Some(changed))))
     });
 
-    let cb = use_callback(move || {
+    let cb = use_callback(move |_| {
         // Create the user's task
         let fut = rc.reset_and_run_in(&mut future);
 
@@ -54,7 +54,7 @@ where
         })
     });
 
-    let mut task = use_hook(|| Signal::new(cb()));
+    let mut task = use_hook(|| Signal::new(cb(())));
 
     use_hook(|| {
         let mut changed = changed.take().unwrap();
@@ -67,7 +67,7 @@ where
                 task.write().cancel();
 
                 // Start a new task
-                task.set(cb());
+                task.set(cb(()));
             }
         })
     });
@@ -110,7 +110,7 @@ pub struct Resource<T: 'static> {
     value: Signal<Option<T>>,
     task: Signal<Task>,
     state: Signal<UseResourceState>,
-    callback: UseCallback<Task>,
+    callback: UseCallback<(), Task>,
 }
 
 impl<T> PartialEq for Resource<T> {
@@ -174,7 +174,7 @@ impl<T> Resource<T> {
     /// ```
     pub fn restart(&mut self) {
         self.task.write().cancel();
-        let new_task = self.callback.call();
+        let new_task = self.callback.call(());
         self.task.set(new_task);
     }