react/use_ref/
use_ref_js.rs

1use 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}