React & TypeScript Quiz
React & TypeScript Quiz — Study Guide
React & TypeScript: Comprehensive Study Guide
React powers millions of modern web apps, and TypeScript makes those apps safer and easier to maintain. Together, they form one of the most in-demand skill sets in frontend development. This guide covers everything from core hooks to performance optimization, accessibility, and Next.js server components — exactly what you need to ace the quiz.
Hooks: The Foundation of Modern React
Hooks let you use state and lifecycle features inside function components. Every hook starts with use.
useEffect
useEffect runs side effects (data fetching, subscriptions, DOM manipulation) after rendering.
useEffect(() => {
console.log("Runs after every render");
});useEffect(() => {
console.log("Runs ONCE on mount — empty array = no dependencies");
}, []);
useEffect(() => {
console.log("Runs when userId changes");
}, [userId]);
Key rule: An empty dependency array[]means the effect runs only once, after the initial render — likecomponentDidMount.
useRef
useRef gives you a mutable container that does not trigger re-renders when changed. Use it for:
const inputRef = useRef<HTMLInputElement>(null);const focusInput = () => {
inputRef.current?.focus(); // Direct DOM access
};
useReducer
An alternative to useState for complex state logic — similar to Redux but built-in.
type Action = { type: "increment" } | { type: "decrement" };function reducer(state: number, action: Action): number {
switch (action.type) {
case "increment": return state + 1;
case "decrement": return state - 1;
}
}
const [count, dispatch] = useReducer(reducer, 0);
Performance Optimization
React.memo
React.memo is a higher-order component that prevents re-rendering when props haven't changed (shallow comparison).
const Button = React.memo(({ label }: { label: string }) => {
return <button>{label}</button>;
});⚠️React.memodoes not help if you pass new object/function references every render. Combine withuseCallbackfor functions.
useMemo
useMemo caches the result of a computation between renders.
const sortedList = useMemo(() => {
return [...items].sort((a, b) => a.name.localeCompare(b.name));
}, [items]);When NOT to use useMemo:
TypeScript in React
type vs interface
| Feature | type | interface |
|---|---|---|
| Extending | Via & intersection | Via extends |
| Declaration merging | ❌ No | ✅ Yes |
| Union types | ✅ Yes | ❌ No |
| General recommendation | Primitives, unions | Object shapes, classes |
type Status = "loading" | "success" | "error"; // Union — use typeinterface User {
id: number;
name: string;
}
Both work for most component props, but interface is preferred for public APIs due to declaration merging.
Forms and Inputs
Controlled inputs bind value to state; uncontrolled inputs use useRef.
const [email, setEmail] = useState("");<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
For TypeScript, type your event handlers: React.ChangeEvent.
Data Fetching & Async
Fetching Inside useEffect
useEffect(() => {
const controller = new AbortController();
fetch("/api/data", { signal: controller.signal })
.then(res => res.json())
.then(setData);
return () => controller.abort(); // Cleanup on unmount
}, []);Suspense
Suspense lets you declaratively handle loading states for async operations:
<Suspense fallback={<Spinner />}>
<UserProfile />
</Suspense>React Internals: Virtual DOM & Reconciliation
React keeps a Virtual DOM — a lightweight JavaScript copy of the real DOM. When state changes:
Lists and Keys: Always provide stable key props in lists so React can efficiently reconcile:
{users.map(user => (
<UserCard key={user.id} user={user} /> // ✅ stable ID
))}Never use array index as a key if the list can reorder.
Next.js & Server Components
Next.js 13+ introduced React Server Components (RSC):
| Server Components | Client Components | |
|---|---|---|
| Runs on | Server only | Browser (+ server for SSR) |
| Can use hooks | ❌ No | ✅ Yes |
| Can fetch data | ✅ Directly | Via useEffect / SWR |
| Bundle size impact | None | Adds to JS bundle |
"use client" at the top of the file.CSS in React
Common approaches:
styles.classNamestyle={{ color: "red" }} (camelCase properties)Web Vitals & Accessibility
Core Web Vitals
Accessibility & ARIA
Always prefer semantic HTML. Use ARIA only when native elements aren't enough:
// ✅ Prefer semantic HTML
<button onClick={handleClick}>Submit</button>// When you must use a div as interactive element
<div
role="button"
tabIndex={0}
aria-label="Close dialog"
onClick={handleClose}
onKeyDown={handleKeyDown}
/>
Key ARIA attributes:
aria-label — names an element for screen readersaria-hidden="true" — hides decorative elementsaria-live — announces dynamic content updatesrole — defines the element's semantic roleKey Takeaways
[] runs once after mount; always clean up subscriptions to avoid memory leaks.type vs interface: use type for unions/primitives, interface for object shapes that may be extended.key props in lists — using array indexes as keys causes subtle bugs when lists reorder.