memo.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #[tokio::test]
  2. async fn memo_updates() {
  3. use std::cell::RefCell;
  4. use dioxus::prelude::*;
  5. thread_local! {
  6. static VEC_SIGNAL: RefCell<Option<Signal<Vec<usize>, SyncStorage>>> = const { RefCell::new(None) };
  7. }
  8. fn app() -> Element {
  9. let mut vec = use_signal_sync(|| vec![0, 1, 2]);
  10. // Signals should update if they are changed from another thread
  11. use_hook(|| {
  12. VEC_SIGNAL.with(|cell| {
  13. *cell.borrow_mut() = Some(vec);
  14. });
  15. std::thread::spawn(move || {
  16. std::thread::sleep(std::time::Duration::from_millis(100));
  17. vec.push(5);
  18. });
  19. });
  20. let len = vec.len();
  21. let len_memo = use_memo(move || vec.len());
  22. // Make sure memos that update in the middle of a component work
  23. if generation() < 2 {
  24. vec.push(len);
  25. }
  26. // The memo should always be up to date
  27. assert_eq!(vec.len(), len_memo());
  28. rsx! {
  29. for i in 0..len {
  30. Child {
  31. index: i,
  32. vec,
  33. }
  34. }
  35. }
  36. }
  37. #[component]
  38. fn Child(index: usize, vec: Signal<Vec<usize>, SyncStorage>) -> Element {
  39. // This memo should not rerun after the element is removed
  40. let item = use_memo(move || vec.read()[index]);
  41. rsx! {
  42. div { "Item: {item}" }
  43. }
  44. }
  45. let mut dom = VirtualDom::new(app);
  46. dom.rebuild_in_place();
  47. let mut signal = VEC_SIGNAL.with(|cell| (*cell.borrow()).unwrap());
  48. // Wait for the signal to update
  49. for _ in 0..3 {
  50. dom.wait_for_work().await;
  51. dom.render_immediate(&mut dioxus::dioxus_core::NoOpMutations);
  52. println!("Signal: {signal:?}");
  53. }
  54. assert_eq!(signal(), vec![0, 1, 2, 3, 4, 5]);
  55. // Remove each element from the vec
  56. for _ in 0..6 {
  57. signal.pop();
  58. dom.wait_for_work().await;
  59. dom.render_immediate(&mut dioxus::dioxus_core::NoOpMutations);
  60. println!("Signal: {signal:?}");
  61. }
  62. }