Back
Syntax
Study
Editor
Mode:
HTML
CSS
JavaScript
PHP
Reset
Run »
HTML / CSS / JS
import { useReducer, useRef, useState, type RefObject } from "react"; // useState — explicit generic when initial value is null interface UserProfile { id: number; name: string; avatar: string } function useProfile() { const [profile, setProfile] = useState<UserProfile | null>(null); const [loading, setLoading] = useState(false); // inferred: boolean async function load(userId: number) { setLoading(true); const res = await fetch(`/api/users/${userId}`); const data = (await res.json()) as UserProfile; setProfile(data); setLoading(false); } return { profile, loading, load }; } // useRef — DOM ref (RefObject, current is readonly) function FocusInput() { const inputRef: RefObject<HTMLInputElement> = useRef(null); const focusInput = () => { inputRef.current?.focus(); // safe optional chain }; return ( <> <input ref={inputRef} type="text" /> <button onClick={focusInput}>Focus</button> </> ); } // useReducer — typed state machine interface CartState { items: { id: number; qty: number }[]; total: number } type CartAction = | { type: "ADD"; id: number; price: number } | { type: "REMOVE"; id: number; price: number } | { type: "CLEAR" }; function cartReducer(state: CartState, action: CartAction): CartState { switch (action.type) { case "ADD": return { ...state, items: [...state.items, { id: action.id, qty: 1 }], total: state.total + action.price }; case "REMOVE": return { ...state, items: state.items.filter(i => i.id !== action.id), total: state.total - action.price }; case "CLEAR": return { items: [], total: 0 }; } } function Cart() { const [cart, dispatch] = useReducer(cartReducer, { items: [], total: 0 }); return <div>Items: {cart.items.length}, Total: ${cart.total}</div>; }
Result
Open