유틸리티 훅
useInterval, useAnimationFrame, useTween, useSpring, useMeasure, useBreakpoint, useLocalStorage.
Text.js는 타이머, 애니메이션, 측정, 영구 저장용 훅을 제공해요. 타이머와 애니메이션은 렌더러의 프레임 주기를 따라요.
타이머
useInterval(refresh, live ? 1000 : null);useTimeout(() => setHint(false), 3000);두 훅 모두 항상 최신 콜백을 호출해요. null을 전달하면 멈춰요.
useAnimationFrame
useAnimationFrame((delta, elapsed) => setPhase(elapsed / 1000), { isActive: playing });useAnimationFrame은 프레임 슬롯마다 한 번 실행돼요. Text.js는 초당 약 15프레임을 출력하므로, 더 빠르게 애니메이션을 실행하면 기록되지 않는 프레임에 CPU를 쓰게 돼요. 루프는 실행 주기별로 타이머 하나를 공유하고 출력이 일시 중지되면 멈춰요.
useTween과 useSpring
const width = useTween(open ? 32 : 0, { duration: 240, easing: "easeOutCubic" });const offset = useSpring(selected * 2);두 훅 모두 목표를 향해 변화하는 숫자를 반환하고 값이 안정되면 실행을 멈춰요. easings에는 linear, easeOutCubic, easeInOutCubic, easeOutExpo 등이 있어요.
useMeasure
const [ref, { width, height }] = useMeasure();return <Box ref={ref} className="grow">{width > 80 ? <Wide /> : <Narrow />}</Box>;레이아웃은 React가 커밋한 뒤 실행되므로 크기는 한 프레임 뒤에 전달돼요. 크기가 바뀔 때만 다시 렌더링해요.
useBreakpoint
const { breakpoint, up } = useBreakpoint();return up("md") ? <TwoColumns /> : <OneColumn />;| Breakpoint | 열 수 |
|---|---|
xs | 0 |
sm | 60 |
md | 80 |
lg | 110 |
xl | 140 |
중단점은 열 수 기준이에요. 원하는 임곗값을 인수로 전달하세요.
useLocalStorage
const [theme, setTheme] = useLocalStorage("theme", "geistDark");useLocalStorage는 JSON을 localStorage에 저장하고, 브라우저 밖에서는 메모리에 저장해요. 같은 키를 공유하는 훅은 탭 사이에서도 동기화된 상태를 유지해요.
useClipboard
const { copy, copied } = useClipboard();useKeymap({ y: { label: "Copy id", run: () => copy(deployment.id) } });return <Text color="muted">{copied ? "Copied" : deployment.id}</Text>;<FocusScope>
<FocusScope>는 보이지 않는 포커스 경계예요. trap을 사용하면 오버레이가 없는 <Modal>처럼 Tab과 useInput이 경계 안에 머물러요.
<FocusScope trap={editing}> <Input autoFocus /></FocusScope>