Careeroza
Typing Hooks
useRef
const inputRef = useRef<HTMLInputElement>(null);
inputRef.current?.focus(); // ?. because it is null before mount
const timerRef = useRef<number | null>(null); // a mutable valueuseReducer with Typed Actions
type State = { count: number };
type Action =
| { type: 'increment' }
| { type: 'add'; amount: number }
| { type: 'reset' };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'add': return { count: state.count + action.amount }; // amount is known here
case 'reset': return { count: 0 };
}
}
const [state, dispatch] = useReducer(reducer, { count: 0 });
dispatch({ type: 'add', amount: 5 }); // ✓
dispatch({ type: 'add' }); // ✗ error: amount is requiredContext
type AuthContextValue = { user: User | null; login: (name: string) => void; logout: () => void };
const AuthContext = createContext<AuthContextValue | null>(null);
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be used inside <AuthProvider>');
return ctx; // type is AuthContextValue, never null
}