Current section

Files

Jump to
glendix src glendix react hook.gleam
Raw

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)