React Guide: Components, State, Hooks, Performance and Interview Questions
Updated 28 Oct 2026 7 min read
On this page 17 sections
- 1What React is and why interviews focus on it
- 2Setup
- 3Components and JSX
- 4Props
- 5State
- 6Rendering lists, conditions and keys
- 7Forms
- 8Effects
- 9Other hooks
- 10How rendering works
- 11Performance
- 12Context, global state and routing
- 13Testing, accessibility and project structure
- 14Class components and older ideas you may be asked about
- 15Common beginner mistakes
- 16Frequently asked interview questions
- 17Practice
What React is and why interviews focus on it
React is a JavaScript library for building user interfaces from small, reusable components. You describe what the screen should look like for the current data, and React updates the page when the data changes. It is the most requested frontend library in job listings. Interviews test whether you understand how rendering works (state, props, effects, keys), not just whether you can follow a tutorial. Be comfortable with modern JavaScript first, especially closures, destructuring and array methods (JavaScript essentials). The frontend roadmap shows what surrounds React.
1. Setup
npm create vite@latest my-app -- --template react
cd my-app && npm install && npm run dev
For production apps, many teams use a framework such as Next.js, which adds routing, server rendering and data fetching on top of React.
2. Components and JSX
A component is a function that returns UI written in JSX (HTML-like syntax that compiles to JavaScript).
function Greeting({ name }) {
return <h2>Hello, {name}!</h2>;
}
export default function App() {
return (
<>
<Greeting name="Asha" />
<Greeting name="Ravi" />
</>
);
}
Rules: names start with a capital letter; return one root element or a fragment (<>...</>); use className instead of class and camelCase for attributes (onClick); put JavaScript expressions in braces. JSX is not a template language: it is function calls (React.createElement or the modern JSX transform) in disguise.
3. Props
Props are the read-only inputs of a component and flow from parent to child (one-way data flow). To let a child talk to its parent, pass a function.
function JobCard({ title, company, onSave, featured = false }) {
return (
<article className={featured ? "card featured" : "card"}>
<h3>{title}</h3>
<p>{company}</p>
<button onClick={() => onSave(title)}>Save</button>
</article>
);
}
children is a special prop for nested content. Never modify props.
4. State
State is a component's memory. Changing it with the setter triggers a re-render.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount((c) => c + 1)}>
Clicked {count} times
</button>
);
}
Important rules:
- Never mutate state (
items.push(x)thensetItems(items)will not re-render properly). Create new values:setItems([...items, x]),setUser({ ...user, name: "Ravi" }). - State updates are batched and asynchronous: the variable keeps its old value until the next render. Use the functional form
setCount(c => c + 1)when the new value depends on the old one. - Keep state minimal; derive values instead of storing them. If something can be calculated from props or other state during render, do not put it in state.
- Lifting state up: when two components need the same data, move the state to their closest common parent.
- Component state resets when the component is removed from the tree or its key changes.
5. Rendering lists, conditions and keys
function JobList({ jobs }) {
if (jobs.length === 0) return <p>No jobs yet.</p>;
return (
<ul>
{jobs.map((job) => (
<li key={job.id}>{job.title}</li>
))}
</ul>
);
}
Conditional rendering: cond && <X />, ternaries and early returns. Beware {count && <X />} when count is 0, because it renders 0. A key must be stable and unique among siblings. Keys let React match old and new items; using the array index as a key causes bugs when items are reordered, inserted or removed (wrong state and input values stay attached to the wrong item).
6. Forms
Controlled inputs take their value from state:
function SearchBox({ onSearch }) {
const [text, setText] = useState("");
return (
<form
onSubmit={(e) => {
e.preventDefault();
onSearch(text.trim());
}}
>
<input value={text} onChange={(e) => setText(e.target.value)} />
<button>Search</button>
</form>
);
}
Uncontrolled inputs keep their value in the DOM and are read through a ref or FormData. For large forms, libraries such as React Hook Form reduce re-renders and handle validation.
7. Effects
useEffect runs after render and is for synchronising with things outside React: network requests, timers, subscriptions, browser APIs.
useEffect(() => {
const controller = new AbortController();
fetch(`/api/jobs?q=${query}`, { signal: controller.signal })
.then((r) => {
if (!r.ok) throw new Error("Request failed");
return r.json();
})
.then(setJobs)
.catch((err) => {
if (err.name !== "AbortError") setError(err.message);
});
return () => controller.abort(); // cleanup runs before the next effect and on unmount
}, [query]); // re-run when query changes
- The dependency array:
[]runs once after the first render,[a, b]runs whenaorbchange, and no array runs after every render. Include every reactive value the effect uses. - Always provide cleanup for timers, subscriptions and requests to avoid leaks and race conditions (an older request finishing after a newer one).
- In development, React's Strict Mode intentionally runs effects twice to expose missing cleanup; this is not a bug.
- You may not need an effect: do not use effects to calculate values from props or state (compute during render) or to respond to user events (use event handlers).
- Show loading and error states for every request. For real apps, prefer a data-fetching library or framework features over hand-written effects.
8. Other hooks
useRef: a mutable box that does not trigger re-renders; use for DOM access (focus an input) and storing values such as timer idsuseMemo: cache an expensive calculation;useCallback: cache a function identity; use only when profiling shows a needuseContext: read shared values (theme, current user) without passing props through many layersuseReducer: manage complex state with a(state, action) => newStatefunction; good when several updates are relateduseLayoutEffect,useId,useTransitionanduseDeferredValuefor advanced cases- Custom hooks are functions starting with
usethat reuse stateful logic:
function useLocalStorage(key, initial) {
const [value, setValue] = useState(() => {
const saved = localStorage.getItem(key);
return saved ? JSON.parse(saved) : initial;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
Rules of hooks: call hooks only at the top level of a component or custom hook (not in loops, conditions or nested functions) and only from React functions. React relies on the call order to match state to each hook.
9. How rendering works
- A state change schedules a render: React calls your component function to get a new description of the UI (the virtual DOM, a tree of plain objects)
- React reconciles: it compares the new tree with the previous one (the "diffing" algorithm, which assumes elements of different types produce different trees and uses keys to match list items)
- It applies only the minimal DOM changes (the commit phase)
Key facts: a component re-renders when its state changes, when its parent re-renders, or when context it reads changes. A re-render does not mean the DOM changes. Components should be pure: the same props and state give the same output, with no side effects during render.
10. Performance
- Do not optimise early; measure with React DevTools Profiler
React.memoskips re-rendering a component when its props are unchanged (compared shallowly); pair with stable props (useCallback,useMemo)- Keep state close to where it is used so fewer components re-render
- Virtualise long lists (render only visible rows) and lazy-load with
React.lazyandSuspenseto split code - Avoid creating huge objects or inline functions in hot paths only if profiling shows a problem
- New compiler tooling can add memoisation automatically; understand the manual tools first
11. Context, global state and routing
Context is great for rarely changing values such as theme and auth. For frequently changing shared state, consider libraries such as Zustand or Redux Toolkit. For server data (loading, caching, refetching), use TanStack Query or your framework's data layer instead of putting responses into global state. Use React Router (or file-based routing in Next.js) for pages.
12. Testing, accessibility and project structure
- Test behaviour with React Testing Library and Jest or Vitest: render, interact as a user would, assert on what is visible
- Accessibility: semantic HTML, labels for inputs, keyboard focus, alt text, sufficient colour contrast
- Organise by feature (
features/jobs/JobList.jsx), keep components small and reusable
13. Class components and older ideas you may be asked about
Lifecycle methods: componentDidMount (effect after the first render), componentDidUpdate, componentWillUnmount (cleanup). Hooks replaced most class usage, but "map the lifecycle to hooks" is a common question. Also know higher-order components, render props and error boundaries (a class component that catches render errors in its children).
14. Common beginner mistakes
- Mutating state or arrays directly
- Using the array index as a key for dynamic lists
- Missing dependencies, or a missing cleanup, in
useEffect - Storing derived data in state, then fighting to keep it in sync
- Fetching data in many components with no loading or error handling
- Putting everything in one huge component
- Calling setState during render (infinite loops)
15. Frequently asked interview questions
- What is React? Why use it?
- What is the virtual DOM? How does reconciliation work?
- State vs props; why is data flow one-way?
- Controlled vs uncontrolled components
- Why are keys important? Why is index a poor key?
- Explain
useEffectand the dependency array; how do you clean up? - What are the rules of hooks, and why do they exist?
useMemovsuseCallbackvsReact.memo- What is prop drilling? How do you avoid it?
- When does a component re-render?
- What is lifting state up?
useStatevsuseReducer; when would you use context?- What is a custom hook? Write one.
- How do you handle errors in React? (error boundaries)
- How would you optimise a slow list of 10,000 items?
16. Practice
Build a job-search page: a search box, filter chips, a list, a detail page and saved jobs stored in localStorage, using a public API. Add loading and error states, deploy it and link it from your resume. Then explain each hook you used and why. Portfolio project ideas can guide what to build next, and the Git guide covers publishing it.
Found this useful? Share it with a friend.