H
Hooks
Type-safe React hooks including useState, useEffect, useRef, useReducer, and custom hooks.
Code
typescript
1import { useState, useEffect, useRef, useReducer, useCallback, useMemo } from "react";2 3// useState with type inference4function Counter() {5 const [count, setCount] = useState(0); // inferred as number6 const [name, setName] = useState<string | null>(null); // explicit union type7 8 return (9 <div>10 <p>Count: {count}</p>11 <button onClick={() => setCount((c) => c + 1)}>Increment</button>12 <button onClick={() => setName("Alice")}>Set Name</button>13 </div>14 );15}16 17// useRef with proper typing18function TextInput() {19 const inputRef = useRef<HTMLInputElement>(null);20 const renderCount = useRef(0); // mutable ref for values21 22 useEffect(() => {23 renderCount.current += 1;24 });25 26 const focusInput = () => {27 inputRef.current?.focus(); // optional chaining for null safety28 };29 30 return (31 <div>32 <input ref={inputRef} type="text" />33 <button onClick={focusInput}>Focus</button>34 <p>Renders: {renderCount.current}</p>35 </div>36 );37}38 39// useReducer with typed state and actions40interface State {41 count: number;42 error: string | null;43}44 45type Action =46 | { type: "increment" }47 | { type: "decrement" }48 | { type: "reset"; payload: number }49 | { type: "setError"; payload: string };50 51function reducer(state: State, action: Action): State {52 switch (action.type) {53 case "increment":54 return { ...state, count: state.count + 1, error: null };55 case "decrement":56 return { ...state, count: state.count - 1, error: null };57 case "reset":58 return { ...state, count: action.payload, error: null };59 case "setError":60 return { ...state, error: action.payload };61 default:62 return state;63 }64}65 66function ReducerExample() {67 const [state, dispatch] = useReducer(reducer, { count: 0, error: null });68 69 return (70 <div>71 <p>Count: {state.count}</p>72 {state.error && <p className="error">{state.error}</p>}73 <button onClick={() => dispatch({ type: "increment" })}>+</button>74 <button onClick={() => dispatch({ type: "decrement" })}>-</button>75 <button onClick={() => dispatch({ type: "reset", payload: 0 })}>Reset</button>76 </div>77 );78}79 80// Custom hook with generics81function useLocalStorage<T>(key: string, initialValue: T) {82 const [storedValue, setStoredValue] = useState<T>(() => {83 try {84 const item = window.localStorage.getItem(key);85 return item ? JSON.parse(item) : initialValue;86 } catch {87 return initialValue;88 }89 });90 91 const setValue = (value: T | ((val: T) => T)) => {92 const valueToStore = value instanceof Function ? value(storedValue) : value;93 setStoredValue(valueToStore);94 window.localStorage.setItem(key, JSON.stringify(valueToStore));95 };96 97 return [storedValue, setValue] as const;98}99 100// Usage101function App() {102 const [theme, setTheme] = useLocalStorage<"light" | "dark">("theme", "light");103 return <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>{theme}</button>;104}Run this example locally
$ npm install react react-dom @types/react @types/react-dom