React interviews often rely on contrast questions such as props vs state, state vs ref, useEffect vs useLayoutEffect, and Context vs Redux.
- Comparisons reveal trade-offs
- Many pairs differ by ownership, timing, or performance
- Use cases matter more than memorized slogans
Many React bugs come from mutable state, wrong keys, bad effect dependencies, overused context, and mixing too much logic into UI components.
- Do not mutate state directly
- Missing dependencies cause subtle bugs
- Too much state or context makes components harder to reason about
Data usually flows down from parent to child, while child-to-parent and sibling communication happen through callbacks, lifted state, or shared providers.
- Parent-to-child uses props
- Child-to-parent uses callback props
- Composition is preferred over inheritance in React
React supports several conditional rendering styles, and returning `null` is the normal way to render nothing.
- Use the simplest pattern for the case
- Ternaries and logical && are common
- Returning null is valid
Context lets a value be shared through a subtree without manually threading props through every intermediate component.
- Provider supplies the value
- Consumers or useContext read it
- Context is useful for truly shared cross-cutting values
Context is not a full performance or tooling replacement for every state management problem, and global state should be introduced only when local state is no longer enough.
- Not all shared data needs Redux
- Context updates can fan out widely
- Global state should solve a real coordination problem
Custom hooks let you extract reusable stateful logic without changing the component tree structure.
- Custom hooks are functions that use hooks
- They share logic, not rendered UI
- Naming them with `use` signals hook behavior
React data fetching is about both getting data and managing cache, loading, error, cancellation, and freshness correctly.
- Server state behaves differently from local UI state
- Race conditions happen when requests overlap
- Libraries like TanStack Query and SWR help with caching and synchronization
useEffect is a common place for data fetching and subscriptions, but async work must be cleaned up carefully to avoid races and leaks.
- Track loading and error states
- Avoid updating unmounted components
- Cleanup matters for listeners, sockets, and in-flight work
React describes what the UI should look like for a given state and builds it from reusable components.
- Declarative code describes desired UI
- Components encapsulate markup, behavior, and reuse
- Composition is central to React design
Error boundaries prevent a rendering error in one subtree from crashing the entire visible application tree.
- They catch errors during rendering, lifecycle, and constructors below them
- They do not catch every async error
- They are implemented with class components
Controlled components keep form values in React state, while uncontrolled components rely more on the DOM and refs.
- Controlled forms are usually easier to validate and coordinate
- Checkboxes, selects, and textareas have input-specific patterns
- Large forms often benefit from libraries