Current section
Files
Jump to
Current section
Files
src/glendix/react/hook.gleam
// React Hooks - useState, useEffect ๋ฑ
import gleam/dynamic.{type Dynamic}
import gleam/option.{type Option, None}
import glendix/react.{type Context, type Promise, type Ref}
// === useState ===
/// ์ํ ํ
. #(ํ์ฌ๊ฐ, ์ธํฐํจ์) ํํ ๋ฐํ
@external(javascript, "./hook_ffi.mjs", "use_state")
pub fn use_state(initial: a) -> #(a, fn(a) -> Nil)
/// useState ์
๋ฐ์ดํฐ ํจ์ ๋ณํ (stale closure ๋ฐฉ์ง)
/// ์ธํฐ์ fn(prev) -> next ํํ์ ์
๋ฐ์ดํฐ ํจ์๋ฅผ ์ ๋ฌ
@external(javascript, "./hook_ffi.mjs", "use_state_updater")
pub fn use_state_(initial: a) -> #(a, fn(fn(a) -> a) -> Nil)
// === useEffect ===
/// ์์กด์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ์คํ
@external(javascript, "./hook_ffi.mjs", "use_effect")
pub fn use_effect(effect_fn: fn() -> Nil, deps: List(a)) -> Nil
/// ๋งค ๋ ๋๋ง๋ง๋ค ์คํ (deps ์์)
@external(javascript, "./hook_ffi.mjs", "use_effect_always")
pub fn use_effect_always(effect_fn: fn() -> Nil) -> Nil
/// ๋ง์ดํธ ์ ํ ๋ฒ๋ง ์คํ (deps = [])
@external(javascript, "./hook_ffi.mjs", "use_effect_once")
pub fn use_effect_once(effect_fn: fn() -> Nil) -> Nil
// === useEffect (cleanup ๋ฐํ) ===
// Gleam fn() -> fn() -> Nil = JS์์ ํจ์๋ฅผ ๋ฐํํ๋ ํจ์ โ React cleanup์ผ๋ก ์ธ์
/// ์์กด์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ์คํ (cleanup ํจ์ ๋ฐํ)
@external(javascript, "./hook_ffi.mjs", "use_effect")
pub fn use_effect_cleanup(setup: fn() -> fn() -> Nil, deps: List(a)) -> Nil
/// ๋งค ๋ ๋๋ง๋ง๋ค ์คํ + cleanup
@external(javascript, "./hook_ffi.mjs", "use_effect_always")
pub fn use_effect_always_cleanup(setup: fn() -> fn() -> Nil) -> Nil
/// ๋ง์ดํธ ์ ํ ๋ฒ๋ง ์คํ + cleanup
@external(javascript, "./hook_ffi.mjs", "use_effect_once")
pub fn use_effect_once_cleanup(setup: fn() -> fn() -> Nil) -> Nil
// === useLayoutEffect ===
// DOM ๋ณ๊ฒฝ ํ ๋ธ๋ผ์ฐ์ ํ์ธํธ ์ ๋๊ธฐ ์คํ
/// ์์กด์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ๋ ์ด์์ ์ดํํธ ์คํ
@external(javascript, "./hook_ffi.mjs", "use_layout_effect")
pub fn use_layout_effect(effect_fn: fn() -> Nil, deps: List(a)) -> Nil
/// ๋งค ๋ ๋๋ง๋ง๋ค ๋ ์ด์์ ์ดํํธ ์คํ (deps ์์)
@external(javascript, "./hook_ffi.mjs", "use_layout_effect_always")
pub fn use_layout_effect_always(effect_fn: fn() -> Nil) -> Nil
/// ๋ง์ดํธ ์ ํ ๋ฒ๋ง ๋ ์ด์์ ์ดํํธ ์คํ (deps = [])
@external(javascript, "./hook_ffi.mjs", "use_layout_effect_once")
pub fn use_layout_effect_once(effect_fn: fn() -> Nil) -> Nil
// === useLayoutEffect (cleanup ๋ฐํ) ===
/// ์์กด์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ๋ ์ด์์ ์ดํํธ ์คํ (cleanup ํจ์ ๋ฐํ)
@external(javascript, "./hook_ffi.mjs", "use_layout_effect")
pub fn use_layout_effect_cleanup(
setup: fn() -> fn() -> Nil,
deps: List(a),
) -> Nil
/// ๋งค ๋ ๋๋ง๋ง๋ค ๋ ์ด์์ ์ดํํธ ์คํ + cleanup
@external(javascript, "./hook_ffi.mjs", "use_layout_effect_always")
pub fn use_layout_effect_always_cleanup(setup: fn() -> fn() -> Nil) -> Nil
/// ๋ง์ดํธ ์ ํ ๋ฒ๋ง ๋ ์ด์์ ์ดํํธ ์คํ + cleanup
@external(javascript, "./hook_ffi.mjs", "use_layout_effect_once")
pub fn use_layout_effect_once_cleanup(setup: fn() -> fn() -> Nil) -> Nil
// === useInsertionEffect ===
// CSS-in-JS์ฉ. DOM ๋ณ๊ฒฝ ์ ์คํ
/// ์์กด์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ์ฝ์
์ดํํธ ์คํ
@external(javascript, "./hook_ffi.mjs", "use_insertion_effect")
pub fn use_insertion_effect(effect_fn: fn() -> Nil, deps: List(a)) -> Nil
/// ๋งค ๋ ๋๋ง๋ง๋ค ์ฝ์
์ดํํธ ์คํ (deps ์์)
@external(javascript, "./hook_ffi.mjs", "use_insertion_effect_always")
pub fn use_insertion_effect_always(effect_fn: fn() -> Nil) -> Nil
/// ๋ง์ดํธ ์ ํ ๋ฒ๋ง ์ฝ์
์ดํํธ ์คํ (deps = [])
@external(javascript, "./hook_ffi.mjs", "use_insertion_effect_once")
pub fn use_insertion_effect_once(effect_fn: fn() -> Nil) -> Nil
// === useInsertionEffect (cleanup ๋ฐํ) ===
/// ์์กด์ฑ ๋ฐฐ์ด๊ณผ ํจ๊ป ์ฝ์
์ดํํธ ์คํ (cleanup ํจ์ ๋ฐํ)
@external(javascript, "./hook_ffi.mjs", "use_insertion_effect")
pub fn use_insertion_effect_cleanup(
setup: fn() -> fn() -> Nil,
deps: List(a),
) -> Nil
/// ๋งค ๋ ๋๋ง๋ง๋ค ์ฝ์
์ดํํธ ์คํ + cleanup
@external(javascript, "./hook_ffi.mjs", "use_insertion_effect_always")
pub fn use_insertion_effect_always_cleanup(setup: fn() -> fn() -> Nil) -> Nil
/// ๋ง์ดํธ ์ ํ ๋ฒ๋ง ์ฝ์
์ดํํธ ์คํ + cleanup
@external(javascript, "./hook_ffi.mjs", "use_insertion_effect_once")
pub fn use_insertion_effect_once_cleanup(setup: fn() -> fn() -> Nil) -> Nil
// === useMemo / useCallback ===
/// ๋ฉ๋ชจ์ด์ ์ด์
๋ ๊ฐ ๊ณ์ฐ
@external(javascript, "./hook_ffi.mjs", "use_memo")
pub fn use_memo(compute: fn() -> a, deps: List(b)) -> a
/// ๋ฉ๋ชจ์ด์ ์ด์
๋ ์ฝ๋ฐฑ
@external(javascript, "./hook_ffi.mjs", "use_callback")
pub fn use_callback(callback: fn(a) -> b, deps: List(c)) -> fn(a) -> b
// === useRef ===
/// ref ์์ฑ
@external(javascript, "./hook_ffi.mjs", "use_ref")
pub fn use_ref(initial: a) -> Ref(a)
/// ์ด๊ธฐ๊ฐ ์๋ ref ์์ฑ (None์ผ๋ก ์ด๊ธฐํ)
pub fn use_ref_() -> Ref(Option(a)) {
use_ref(None)
}
/// ref ํ์ฌ ๊ฐ ์ฝ๊ธฐ
/// @deprecated โ `glendix/react/ref.current` ์ฌ์ฉ ๊ถ์ฅ
@external(javascript, "./hook_ffi.mjs", "get_ref_current")
pub fn get_ref(ref: Ref(a)) -> a
/// ref ํ์ฌ ๊ฐ ์ค์
/// @deprecated โ `glendix/react/ref.assign` ์ฌ์ฉ ๊ถ์ฅ
@external(javascript, "./hook_ffi.mjs", "set_ref_current")
pub fn set_ref(ref: Ref(a), value: a) -> Nil
// === useReducer ===
/// ๋ฆฌ๋์ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ
@external(javascript, "./hook_ffi.mjs", "use_reducer")
pub fn use_reducer(
reducer: fn(state, action) -> state,
initial: state,
) -> #(state, fn(action) -> Nil)
/// ๋ฆฌ๋์ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ (์ง์ฐ ์ด๊ธฐํ โ init(initial_arg)๋ก ์ด๊ธฐ ์ํ ์์ฑ)
@external(javascript, "./hook_ffi.mjs", "use_reducer_lazy")
pub fn use_reducer_(
reducer: fn(state, action) -> state,
initial_arg: a,
init: fn(a) -> state,
) -> #(state, fn(action) -> Nil)
// === useContext ===
/// Context ๊ฐ ์ฝ๊ธฐ
@external(javascript, "./hook_ffi.mjs", "use_context")
pub fn use_context(context: Context(a)) -> a
// === useId ===
/// SSR-safe ๊ณ ์ ID ์์ฑ
@external(javascript, "./hook_ffi.mjs", "use_id")
pub fn use_id() -> String
// === useTransition ===
/// ๋น๊ธด๊ธ ์ํ ์
๋ฐ์ดํธ ํ์
@external(javascript, "./hook_ffi.mjs", "use_transition")
pub fn use_transition() -> #(Bool, fn(fn() -> Nil) -> Nil)
/// ๋น๋๊ธฐ ํธ๋์ง์
(React 19) โ startTransition์ด async ์ฝ๋ฐฑ ์์ฉ
@external(javascript, "./hook_ffi.mjs", "use_transition")
pub fn use_async_transition() -> #(Bool, fn(fn() -> Promise(Nil)) -> Nil)
// === useDeferredValue ===
/// ๊ฐ ์ง์ฐ ์ฒ๋ฆฌ
@external(javascript, "./hook_ffi.mjs", "use_deferred_value")
pub fn use_deferred_value(value: a) -> a
// === useOptimistic (React 19) ===
/// ๋๊ด์ UI ์
๋ฐ์ดํธ
@external(javascript, "./hook_ffi.mjs", "use_optimistic")
pub fn use_optimistic(state: a) -> #(a, fn(a) -> Nil)
/// ๋๊ด์ UI ์
๋ฐ์ดํธ (๋ฆฌ๋์ ๋ณํ โ ์
๋ฐ์ดํธ ํจ์๋ก ๋ณํฉ ๋ก์ง ์ง์ )
@external(javascript, "./hook_ffi.mjs", "use_optimistic_with_update")
pub fn use_optimistic_(state: a, update_fn: fn(a, b) -> a) -> #(a, fn(b) -> Nil)
// === useActionState (React 19) ===
/// ํผ ์ก์
๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ (React 19)
/// action(ํ์ฌ์ํ, ํ์ด๋ก๋) -> ์์ํ, ๋ฐํ: #(์ํ, ํผ์ก์
, isPending)
@external(javascript, "./hook_ffi.mjs", "use_action_state")
pub fn use_action_state(
action: fn(state, payload) -> state,
initial_state: state,
) -> #(state, fn(payload) -> Nil, Bool)
// === useImperativeHandle ===
/// ๋ถ๋ชจ์๊ฒ ๋
ธ์ถํ๋ ref ์ธ์คํด์ค ์ปค์คํฐ๋ง์ด์ง
@external(javascript, "./hook_ffi.mjs", "use_imperative_handle")
pub fn use_imperative_handle(
ref: Ref(a),
create: fn() -> a,
deps: List(b),
) -> Nil
// === useState (์ง์ฐ ์ด๊ธฐํ) ===
/// ์ง์ฐ ์ด๊ธฐํ useState (๋น์ผ ์ด๊ธฐ๊ฐ ๊ณ์ฐ ๋ฐฉ์ง, init_fn์ ๋ง์ดํธ ์ ํ ๋ฒ๋ง ํธ์ถ)
@external(javascript, "./hook_ffi.mjs", "use_lazy_state")
pub fn use_lazy_state(init_fn: fn() -> a) -> #(a, fn(a) -> Nil)
/// ์ง์ฐ ์ด๊ธฐํ useState + ์
๋ฐ์ดํฐ ํจ์ ๋ณํ
@external(javascript, "./hook_ffi.mjs", "use_lazy_state_updater")
pub fn use_lazy_state_(init_fn: fn() -> a) -> #(a, fn(fn(a) -> a) -> Nil)
// === useSyncExternalStore ===
/// ์ธ๋ถ ์คํ ์ด ๊ตฌ๋
(Redux/Zustand ํตํฉ์ฉ)
@external(javascript, "./hook_ffi.mjs", "use_sync_external_store")
pub fn use_sync_external_store(
subscribe: fn(fn() -> Nil) -> fn() -> Nil,
get_snapshot: fn() -> a,
) -> a
// === useDebugValue ===
/// ์ปค์คํ
ํ
๋๋ฒ๊ทธ ๊ฐ (React DevTools์ ํ์)
@external(javascript, "./hook_ffi.mjs", "use_debug_value")
pub fn use_debug_value(value: a) -> Nil
/// ์ปค์คํ
ํ
๋๋ฒ๊ทธ ๊ฐ + ํฌ๋งท ํจ์
@external(javascript, "./hook_ffi.mjs", "use_debug_value_format")
pub fn use_debug_value_(value: a, format: fn(a) -> String) -> Nil
// === React.use (React 19) ===
/// Suspense ๊ฒฝ๊ณ ๋ด์์ Promise๋ฅผ ์๋นํ์ฌ ๊ฐ์ ๋ฐํ
/// Promise๊ฐ ๋ฏธ์๋ฃ ์ React๊ฐ Suspense ํด๋ฐฑ์ ํ์ํ๋ค
@external(javascript, "./hook_ffi.mjs", "use_promise")
pub fn use_promise(promise: Promise(a)) -> a
// === useFormStatus (React 19 โ react-dom) ===
/// ํผ ์ ์ถ ์ํ ๊ฐ์ฒด
pub type FormStatus
/// ๊ฐ์ฅ ๊ฐ๊น์ด <form> ๋ถ๋ชจ์ ์ ์ถ ์ํ ๋ฐํ (React 19)
@external(javascript, "./hook_ffi.mjs", "use_form_status")
pub fn use_form_status() -> FormStatus
/// ํผ์ด ํ์ฌ ์ ์ถ ์ค์ธ์ง ์ฌ๋ถ
@external(javascript, "./hook_ffi.mjs", "get_form_status_pending")
pub fn form_pending(status: FormStatus) -> Bool
/// ์ ์ถ๋ FormData (์ ์ถ ์ค์ด ์๋ ๊ฒฝ์ฐ None)
@external(javascript, "./hook_ffi.mjs", "get_form_status_data")
pub fn form_data(status: FormStatus) -> Option(Dynamic)
/// HTTP ๋ฉ์๋ (get ๋๋ post)
@external(javascript, "./hook_ffi.mjs", "get_form_status_method")
pub fn form_method(status: FormStatus) -> String
/// ํผ์ action ํจ์ ์ฐธ์กฐ (์์ผ๋ฉด None)
@external(javascript, "./hook_ffi.mjs", "get_form_status_action")
pub fn form_action(status: FormStatus) -> Option(Dynamic)