useref.rs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. use std::{
  2. cell::{Ref, RefCell, RefMut},
  3. rc::Rc,
  4. };
  5. use dioxus_core::ScopeState;
  6. pub fn use_ref<'a, T: 'static>(cx: &'a ScopeState, f: impl FnOnce() -> T) -> &'a UseRef<T> {
  7. cx.use_hook(|_| UseRef {
  8. update_callback: cx.schedule_update(),
  9. value: Rc::new(RefCell::new(f())),
  10. })
  11. }
  12. pub struct UseRef<T> {
  13. update_callback: Rc<dyn Fn()>,
  14. value: Rc<RefCell<T>>,
  15. }
  16. impl<T> UseRef<T> {
  17. pub fn read(&self) -> Ref<'_, T> {
  18. self.value.borrow()
  19. }
  20. pub fn set(&self, new: T) {
  21. *self.value.borrow_mut() = new;
  22. self.needs_update();
  23. }
  24. pub fn read_write(&self) -> (Ref<'_, T>, &Self) {
  25. (self.read(), self)
  26. }
  27. /// Calling "write" will force the component to re-render
  28. pub fn write(&self) -> RefMut<'_, T> {
  29. self.needs_update();
  30. self.value.borrow_mut()
  31. }
  32. /// Allows the ability to write the value without forcing a re-render
  33. pub fn write_silent(&self) -> RefMut<'_, T> {
  34. self.value.borrow_mut()
  35. }
  36. pub fn needs_update(&self) {
  37. (self.update_callback)();
  38. }
  39. }
  40. impl<T> Clone for UseRef<T> {
  41. fn clone(&self) -> Self {
  42. Self {
  43. update_callback: self.update_callback.clone(),
  44. value: self.value.clone(),
  45. }
  46. }
  47. }