feat: useeffect implemented
This commit is contained in:
1 parent
7a5c403e38
commit
64edc6e1b1
3 files changed
+86
-6
No files matched your search
@@ -16,6 +16,9 @@ pub use usefuture::*;
|
|||||||
mod usecallback;
|
mod usecallback;
|
||||||
pub use usecallback::*;
|
pub use usecallback::*;
|
||||||
|
|
||||||
|
mod useeffect;
|
||||||
|
pub use useeffect::*;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
/// A helper macro for using hooks in async environements.
|
/// A helper macro for using hooks in async environements.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use std::future::Future;
|
|||||||
|
|
||||||
pub fn use_callback<I, G: UseFutureDep, F: Future<Output = ()> + 'static>(
|
pub fn use_callback<I, G: UseFutureDep, F: Future<Output = ()> + 'static>(
|
||||||
cx: &ScopeState,
|
cx: &ScopeState,
|
||||||
//
|
|
||||||
g: G,
|
g: G,
|
||||||
f: impl FnMut(I, G::Out) -> F,
|
f: impl FnMut(I, G::Out) -> F,
|
||||||
) -> &UseCallback<I, G::Out>
|
) -> &UseCallback<I, G::Out>
|
||||||
@@ -26,7 +25,7 @@ where
|
|||||||
|
|
||||||
pub struct UseCallback<I, T> {
|
pub struct UseCallback<I, T> {
|
||||||
f: Rc<RefCell<Option<Box<dyn FnMut(I, T)>>>>,
|
f: Rc<RefCell<Option<Box<dyn FnMut(I, T)>>>>,
|
||||||
f2: Box<dyn Fn(I)>, // f: Rc<RefCell<Option<Box<dyn FnMut(I, T)>>>>,
|
f2: Box<dyn Fn(I)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: 'static, T> std::ops::Deref for UseCallback<I, T> {
|
impl<I: 'static, T> std::ops::Deref for UseCallback<I, T> {
|
||||||
@@ -37,10 +36,6 @@ impl<I: 'static, T> std::ops::Deref for UseCallback<I, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MyThing {}
|
|
||||||
impl<A> MyThing for Box<dyn Fn(A)> {}
|
|
||||||
impl<A, B> MyThing for Box<dyn Fn(A, B)> {}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn demo() {
|
fn demo() {
|
||||||
use dioxus_core::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
@@ -53,6 +48,7 @@ fn demo() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let onsubmit = use_callback(&cx, (name,), my_callback);
|
let onsubmit = use_callback(&cx, (name,), my_callback);
|
||||||
|
|
||||||
async fn my_callback(event: UiEvent<()>, name: (i32,)) {
|
async fn my_callback(event: UiEvent<()>, name: (i32,)) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
use dioxus_core::{ScopeState, TaskId};
|
||||||
|
use std::{any::Any, cell::Cell, future::Future};
|
||||||
|
|
||||||
|
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
|
||||||
|
///
|
||||||
|
/// - dependencies: a tuple of references to values that are PartialEq + Clone
|
||||||
|
pub fn use_effect<'a, T: 'static, F: Future<Output = T> + 'static, D: UseFutureDep>(
|
||||||
|
cx: &'a ScopeState,
|
||||||
|
dependencies: D,
|
||||||
|
future: impl FnOnce(D::Out) -> F,
|
||||||
|
) -> &'a UseEffect {
|
||||||
|
let state = cx.use_hook(move |_| UseEffect {
|
||||||
|
needs_regen: Cell::new(true),
|
||||||
|
task: Cell::new(None),
|
||||||
|
dependencies: Vec::new(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if dependencies.clone().apply(&mut state.dependencies) || state.needs_regen.get() {
|
||||||
|
// We don't need regen anymore
|
||||||
|
state.needs_regen.set(false);
|
||||||
|
|
||||||
|
// Create the new future
|
||||||
|
let fut = future(dependencies.out());
|
||||||
|
|
||||||
|
state.task.set(Some(cx.push_future(async move {
|
||||||
|
fut.await;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
state
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UseEffect {
|
||||||
|
needs_regen: Cell<bool>,
|
||||||
|
task: Cell<Option<TaskId>>,
|
||||||
|
dependencies: Vec<Box<dyn Any>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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(&cx, (), |_| async move {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
|
||||||
|
// runs when a is changed
|
||||||
|
use_effect(&cx, (&cx.props.a,), |(a,)| async move {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
|
||||||
|
// runs when a or b is changed
|
||||||
|
use_effect(&cx, (&cx.props.a, &cx.props.b), |(a, b)| async move {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user