fix: Use Rc for lifecycle management (#4471)
* fix: Use Rc for lifecycle management * Try to unwrap the Rc instead of using both rc and option * Add a test for use drop * fix test name --------- Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
1 parent
79e7739bee
commit
a610aaefc3
2 files changed
+72
-9
No files matched your search
@@ -4,6 +4,7 @@ use crate::{
|
||||
Task,
|
||||
};
|
||||
use std::future::Future;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Get the current scope id
|
||||
@@ -441,15 +442,10 @@ pub fn use_drop<D: FnOnce() + 'static>(destroy: D) {
|
||||
}
|
||||
}
|
||||
|
||||
// We need to impl clone for the lifecycle, but we don't want the drop handler for the closure to be called twice.
|
||||
impl<D: FnOnce()> Clone for LifeCycle<D> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { ondestroy: None }
|
||||
}
|
||||
}
|
||||
|
||||
use_hook(|| LifeCycle {
|
||||
ondestroy: Some(destroy),
|
||||
use_hook(|| {
|
||||
Rc::new(LifeCycle {
|
||||
ondestroy: Some(destroy),
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//! Tests the use_drop hook
|
||||
use dioxus::dioxus_core::use_drop;
|
||||
use dioxus::prelude::*;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
type Shared<T> = Arc<Mutex<T>>;
|
||||
|
||||
#[derive(Clone, Props)]
|
||||
struct AppProps {
|
||||
render_child: Shared<bool>,
|
||||
drop_count: Shared<u32>,
|
||||
}
|
||||
|
||||
impl PartialEq for AppProps {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Arc::ptr_eq(&self.drop_count, &other.drop_count)
|
||||
}
|
||||
}
|
||||
|
||||
fn app(props: AppProps) -> Element {
|
||||
let render_child = props.render_child.clone();
|
||||
let render_child = *render_child.lock().unwrap();
|
||||
println!(
|
||||
"Rendering app component with render_child: {}",
|
||||
render_child
|
||||
);
|
||||
rsx! {
|
||||
if render_child {
|
||||
child_component {
|
||||
drop_count: props.drop_count.clone(),
|
||||
render_child: props.render_child.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn child_component(props: AppProps) -> Element {
|
||||
println!("Rendering child component");
|
||||
use_drop(move || {
|
||||
println!("Child component is being dropped");
|
||||
let mut count = props.drop_count.lock().unwrap();
|
||||
*count += 1;
|
||||
});
|
||||
|
||||
rsx! {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drop_runs() {
|
||||
let drop_count = Arc::new(Mutex::new(0));
|
||||
let render_child = Arc::new(Mutex::new(true));
|
||||
let mut dom = VirtualDom::new_with_props(
|
||||
app,
|
||||
AppProps { drop_count: drop_count.clone(), render_child: render_child.clone() },
|
||||
);
|
||||
|
||||
dom.rebuild_in_place();
|
||||
|
||||
assert_eq!(*drop_count.lock().unwrap(), 0);
|
||||
*render_child.lock().unwrap() = false;
|
||||
|
||||
dom.mark_dirty(ScopeId::APP);
|
||||
dom.render_immediate(&mut dioxus_core::NoOpMutations);
|
||||
|
||||
assert_eq!(*drop_count.lock().unwrap(), 1);
|
||||
*render_child.lock().unwrap() = false;
|
||||
}
|
||||
Reference in new issue
Block a user