use_const.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. use std::rc::Rc;
  2. use dioxus_core::prelude::*;
  3. /// Store constant state between component renders.
  4. ///
  5. /// UseConst allows you to store state that is initialized once and then remains constant across renders.
  6. /// You can only get an immutable reference after initalization.
  7. /// This can be useful for values that don't need to update reactively, thus can be memoized easily
  8. ///
  9. /// ```rust, ignore
  10. /// struct ComplexData(i32);
  11. ///
  12. /// fn Component(cx: Scope) -> Element {
  13. /// let id = use_const(cx, || ComplexData(100));
  14. ///
  15. /// cx.render(rsx! {
  16. /// div { "{id.0}" }
  17. /// })
  18. /// }
  19. /// ```
  20. #[must_use]
  21. pub fn use_const<T: 'static>(
  22. cx: &ScopeState,
  23. initial_state_fn: impl FnOnce() -> T,
  24. ) -> &UseConst<T> {
  25. cx.use_hook(|| UseConst {
  26. value: Rc::new(initial_state_fn()),
  27. })
  28. }
  29. #[derive(Clone)]
  30. pub struct UseConst<T> {
  31. value: Rc<T>,
  32. }
  33. impl<T> PartialEq for UseConst<T> {
  34. fn eq(&self, other: &Self) -> bool {
  35. Rc::ptr_eq(&self.value, &other.value)
  36. }
  37. }
  38. impl<T: core::fmt::Display> core::fmt::Display for UseConst<T> {
  39. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  40. self.value.fmt(f)
  41. }
  42. }
  43. impl<T> UseConst<T> {
  44. pub fn get_rc(&self) -> &Rc<T> {
  45. &self.value
  46. }
  47. }
  48. impl<T> std::ops::Deref for UseConst<T> {
  49. type Target = T;
  50. fn deref(&self) -> &Self::Target {
  51. self.value.as_ref()
  52. }
  53. }
  54. #[test]
  55. fn use_const_makes_sense() {
  56. #[allow(unused)]
  57. fn app(cx: Scope) -> Element {
  58. let const_val = use_const(cx, || vec![0, 1, 2, 3]);
  59. assert!(const_val[0] == 0);
  60. // const_val.remove(0); // Cannot Compile, cannot get mutable reference now
  61. None
  62. }
  63. }