react/use_ref/
use_ref_js.rs1use convert_js::{FromJs, ToJs};
2use std::marker::PhantomData;
3use wasm_bindgen::JsValue;
4
5use super::IntoRefValue;
6
7pub fn use_ref_js<T: ToJs + FromJs>(initial_value: T) -> MutableRefJs<T> {
8 let obj = react_sys::use_ref(&initial_value.to_js());
9 MutableRefJs(obj, PhantomData)
10}
11
12pub fn use_ref_js_with<T: ToJs + FromJs, F: FnOnce() -> T>(
13 get_initial_value: F,
14) -> MutableRefJs<T> {
15 let ref_initialized = react_sys::use_ref_bool(false);
16 let obj = react_sys::use_ref(&JsValue::UNDEFINED);
17 if !ref_initialized.current() {
18 obj.set_current(get_initial_value().to_js())
19 }
20 MutableRefJs(obj, PhantomData)
21}
22
23pub fn use_ref_js_set_as<T: ToJs + FromJs>(value: T) -> MutableRefJs<T> {
24 let obj = react_sys::use_ref(&JsValue::UNDEFINED);
25 obj.set_current(value.to_js());
26 MutableRefJs(obj, PhantomData)
27}
28
29pub struct MutableRefJs<T: ToJs + FromJs>(react_sys::MutableRefObject, PhantomData<T>);
30
31impl<T: ToJs + FromJs> Clone for MutableRefJs<T> {
32 fn clone(&self) -> Self {
33 Self(self.0.clone(), PhantomData)
34 }
35}
36
37impl<T: ToJs + FromJs> AsRef<JsValue> for MutableRefJs<T> {
38 fn as_ref(&self) -> &JsValue {
39 self.0.as_ref()
40 }
41}
42
43impl<T: ToJs + FromJs> ToJs for MutableRefJs<T> {
44 fn to_js(&self) -> JsValue {
45 AsRef::<JsValue>::as_ref(&self.0).clone()
46 }
47}
48
49impl<T: ToJs + FromJs> crate::SafeIntoJsRuntime for MutableRefJs<T> {
50 fn safe_into_js_runtime(self) -> crate::PassedToJsRuntime {
51 crate::PassedToJsRuntime {
52 js_value: self.0.into(),
53 to_persist: None,
54 }
55 }
56}
57
58impl<T, W: IntoRefValue<T> + ToJs + FromJs> super::ReadRef<T> for MutableRefJs<W>
59where
60 <W as FromJs>::Error: std::fmt::Debug,
61{
62 fn current(&self) -> T {
63 let js_value = self.0.current();
64 let w = W::from_js(js_value).unwrap();
65 w.into_ref_value()
66 }
67}
68
69impl<T: IntoRefValue<W>, W: ToJs + FromJs> super::WriteRef<T> for MutableRefJs<W> {
70 fn set_current(&self, v: T) {
71 let w: W = v.into_ref_value();
72 self.0.set_current(w.to_js())
73 }
74}