1
0

use_memo.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. use crate::dependency::Dependency;
  2. use crate::use_signal;
  3. use dioxus_core::prelude::*;
  4. use dioxus_signals::{ReadOnlySignal, Readable, Signal, SignalData};
  5. use dioxus_signals::{Storage, Writable};
  6. /// Creates a new unsync Selector. The selector will be run immediately and whenever any signal it reads changes.
  7. ///
  8. /// Selectors can be used to efficiently compute derived data from signals.
  9. ///
  10. /// ```rust
  11. /// use dioxus::prelude::*;
  12. /// use dioxus_signals::*;
  13. ///
  14. /// fn App() -> Element {
  15. /// let mut count = use_signal(|| 0);
  16. /// let double = use_memo(move || count * 2);
  17. /// count += 1;
  18. /// assert_eq!(double.value(), count * 2);
  19. ///
  20. /// rsx! { "{double}" }
  21. /// }
  22. /// ```
  23. #[track_caller]
  24. pub fn use_memo<R: PartialEq>(f: impl FnMut() -> R + 'static) -> ReadOnlySignal<R> {
  25. use_maybe_sync_memo(f)
  26. }
  27. /// Creates a new Selector that may be sync. The selector will be run immediately and whenever any signal it reads changes.
  28. ///
  29. /// Selectors can be used to efficiently compute derived data from signals.
  30. ///
  31. /// ```rust
  32. /// use dioxus::prelude::*;
  33. /// use dioxus_signals::*;
  34. ///
  35. /// fn App(cx: Scope) -> Element {
  36. /// let mut count = use_signal(cx, || 0);
  37. /// let double = use_memo(cx, move || count * 2);
  38. /// count += 1;
  39. /// assert_eq!(double.value(), count * 2);
  40. ///
  41. /// render! { "{double}" }
  42. /// }
  43. /// ```
  44. #[track_caller]
  45. pub fn use_maybe_sync_memo<R: PartialEq, S: Storage<SignalData<R>>>(
  46. f: impl FnMut() -> R + 'static,
  47. ) -> ReadOnlySignal<R, S> {
  48. use_hook(|| Signal::maybe_sync_memo(f))
  49. }
  50. /// Creates a new unsync Selector with some local dependencies. The selector will be run immediately and whenever any signal it reads or any dependencies it tracks changes
  51. ///
  52. /// Selectors can be used to efficiently compute derived data from signals.
  53. ///
  54. /// ```rust
  55. /// use dioxus::prelude::*;
  56. /// use dioxus_signals::*;
  57. ///
  58. /// fn App(cx: Scope) -> Element {
  59. /// let mut local_state = use_state(cx, || 0);
  60. /// let double = use_memo_with_dependencies(cx, (local_state.get(),), move |(local_state,)| local_state * 2);
  61. /// local_state.set(1);
  62. ///
  63. /// render! { "{double}" }
  64. /// }
  65. /// ```
  66. #[track_caller]
  67. pub fn use_memo_with_dependencies<R: PartialEq, D: Dependency>(
  68. dependencies: D,
  69. f: impl FnMut(D::Out) -> R + 'static,
  70. ) -> ReadOnlySignal<R>
  71. where
  72. D::Out: 'static,
  73. {
  74. use_maybe_sync_selector_with_dependencies(dependencies, f)
  75. }
  76. /// Creates a new Selector that may be sync with some local dependencies. The selector will be run immediately and whenever any signal it reads or any dependencies it tracks changes
  77. ///
  78. /// Selectors can be used to efficiently compute derived data from signals.
  79. ///
  80. /// ```rust
  81. /// use dioxus::prelude::*;
  82. /// use dioxus_signals::*;
  83. ///
  84. /// fn App(cx: Scope) -> Element {
  85. /// let mut local_state = use_state(cx, || 0);
  86. /// let double = use_memo_with_dependencies(cx, (local_state.get(),), move |(local_state,)| local_state * 2);
  87. /// local_state.set(1);
  88. ///
  89. /// render! { "{double}" }
  90. /// }
  91. /// ```
  92. #[track_caller]
  93. pub fn use_maybe_sync_selector_with_dependencies<
  94. R: PartialEq,
  95. D: Dependency,
  96. S: Storage<SignalData<R>>,
  97. >(
  98. dependencies: D,
  99. mut f: impl FnMut(D::Out) -> R + 'static,
  100. ) -> ReadOnlySignal<R, S>
  101. where
  102. D::Out: 'static,
  103. {
  104. let mut dependencies_signal = use_signal(|| dependencies.out());
  105. let selector = use_hook(|| {
  106. Signal::maybe_sync_memo(move || {
  107. let deref = &*dependencies_signal.read();
  108. f(deref.clone())
  109. })
  110. });
  111. let changed = { dependencies.changed(&*dependencies_signal.read()) };
  112. if changed {
  113. dependencies_signal.set(dependencies.out());
  114. }
  115. selector
  116. }