///|
// React Hooks wrappers, aligned with existing use_state style
typealias @dom.JsObscure
///|
extern "js" fn react_use_effect(
effect : @dom.JsObscure,
deps : Array[@dom.JsObscure],
) -> Unit =
#| (effect, deps) => window.React.useEffect(effect, deps)
///|
extern "js" fn react_use_layout_effect(
effect : @dom.JsObscure,
deps : Array[@dom.JsObscure],
) -> Unit =
#| (effect, deps) => window.React.useLayoutEffect(effect, deps)
///|
extern "js" fn react_use_memo(
factory : @dom.JsObscure,
deps : Array[@dom.JsObscure],
) -> @dom.JsObscure =
#| (factory, deps) => window.React.useMemo(factory, deps)
///|
extern "js" fn react_use_callback(
callback : @dom.JsObscure,
deps : Array[@dom.JsObscure],
) -> JsObscure =
#| (callback, deps) => window.React.useCallback(callback, deps)
///|
extern "js" fn react_use_ref(initial : @dom.JsObscure) -> @dom.JsObscure =
#| (initial) => window.React.useRef(initial)
///|
extern "js" fn react_ref_get_value(r : @dom.JsObscure) -> @dom.JsObscure =
#| (ref) => ref.current
///|
extern "js" fn react_ref_set_value(
r : @dom.JsObscure,
value : JsObscure,
) -> Unit =
#| (ref, value) => ref.current = value
///|
extern "js" fn react_use_reducer(
reducer : JsObscure,
initial : JsObscure,
) -> JsObscure =
#| (reducer, initial) => window.React.useReducer(reducer, initial)
///|
fn fn0_to_js_obscure(f : () -> Unit) -> @dom.JsObscure = "%identity"
///|
fn fn1_from_js_obscure(v : JsObscure) -> (JsObscure) -> Unit = "%identity"
///|
// useLayoutEffect
pub fn use_layout_effect_deps(
effect : () -> Unit,
deps : Array[@dom.JsObscure],
) -> Unit {
react_use_layout_effect(fn0_to_js_obscure(effect), deps)
}
///|
// useMemo
pub fn[A] use_memo_deps(factory : () -> A, deps : Array[@dom.JsObscure]) -> A {
let v = react_use_memo(@dom.v_to_js_obscure(factory), deps)
@dom.js_obscure_to_v(v)
}
///|
// useCallback
pub fn[F] use_callback_deps(callback : F, deps : Array[@dom.JsObscure]) -> F {
let v = react_use_callback(@dom.v_to_js_obscure(callback), deps)
@dom.js_obscure_to_v(v)
}
///|
// useEffect
pub fn use_effect_once(effect : () -> Unit) -> Unit {
react_use_effect(fn0_to_js_obscure(effect), [])
}
///|
/// a short hand to turn value into JsObscure in hook deps
pub fn[T] obscure(v : T) -> @dom.JsObscure = "%identity"
///|
pub fn use_effect_deps(
effect : () -> Unit,
deps : Array[@dom.JsObscure],
) -> Unit {
react_use_effect(fn0_to_js_obscure(effect), deps)
}
///|
// useCallback (no argument)
pub fn use_callback0_deps(
f : () -> Unit,
deps : Array[@dom.JsObscure],
) -> () -> Unit {
let raw = react_use_callback(@dom.v_to_js_obscure(f), deps)
@dom.js_obscure_to_v(raw)
}
///|
struct ReactRef[T] {
js_value : @dom.JsObscure
mut _v0 : T
}
///|
pub fn[T] ReactRef::from(v : T) -> ReactRef[T] {
ReactRef::{ js_value: react_use_ref(@dom.v_to_js_obscure(v)), _v0: v }
}
///|
pub fn[T] ReactRef::get(self : ReactRef[T]) -> T {
@dom.js_obscure_to_v(react_ref_get_value(self.js_value))
}
///|
pub fn[T] ReactRef::set(self : ReactRef[T], value : T) -> Unit {
react_ref_set_value(self.js_value, any_to_js_value(value))
self._v0 = value
}
///|
// useRef
pub fn[T] use_ref(initial : T) -> ReactRef[T] {
ReactRef::{
js_value: react_use_ref(@dom.v_to_js_obscure(initial)),
_v0: initial,
}
}
///|
// useReducer
pub fn[S : Default, A] use_reducer(
initial? : S,
reducer : (S, A) -> S,
) -> (S, (A) -> Unit) {
let pair = react_use_reducer(
any_to_js_value(reducer),
any_to_js_value(initial.unwrap_or_default()),
)
let s0 = any_from_js_value(pair.get("0"))
let dispatch_raw = fn1_from_js_obscure(pair.get("1"))
(s0, fn(a : A) { dispatch_raw(any_to_js_value(a)) })
}