Skip to content

1. Components & Props (Very Important)

Components are the building blocks of every React app. Almost every React interview starts here.


1. What is React?

React is a JavaScript library for building user interfaces using reusable components.

Key ideas:

  • Component based
  • Declarative (you describe what the UI should look like, not how to update it)
  • Uses a Virtual DOM for efficient updates
  • One-way data flow (parent → child)

Interview Point

React is a library, not a framework. It only handles the view layer. Routing, data fetching and state management come from other packages.


2. JSX

JSX is a syntax extension that lets you write HTML-like markup inside JavaScript.

jsx
const element = <h1 className="title">Hello Dipak</h1>;

Browsers do not understand JSX. Babel (or SWC) compiles it:

js
const element = React.createElement("h1", { className: "title" }, "Hello Dipak");

JSX Rules

RuleExample
One root elementwrap in <div> or <>...</>
class becomes className<div className="box">
for becomes htmlFor<label htmlFor="name">
Attributes are camelCaseonClick, tabIndex
Expressions in {}<p>{user.name}</p>
Tags must be closed<img />, <br />

Interview Point

JSX is optional. It is syntactic sugar over React.createElement(). Since React 17, the new JSX transform imports jsx() automatically, so you no longer need import React from "react" just for JSX.


3. React.Fragment

A Fragment lets you return multiple elements without adding an extra DOM node.

jsx
function Row() {
  return (
    <>
      <td>Dipak</td>
      <td>Developer</td>
    </>
  );
}

Why it matters

An extra wrapper <div> can break CSS grid, flexbox and valid HTML (a <tr> cannot contain a <div>).

When you need the long form

Use <React.Fragment> when you need a key:

jsx
{items.map((item) => (
  <React.Fragment key={item.id}>
    <dt>{item.term}</dt>
    <dd>{item.desc}</dd>
  </React.Fragment>
))}

The short syntax <> does not accept props.


4. Functional vs Class Components

Functional Component

jsx
function Welcome({ name }) {
  return <h1>Hello {name}</h1>;
}

Class Component

jsx
class Welcome extends React.Component {
  render() {
    return <h1>Hello {this.props.name}</h1>;
  }
}

Comparison

FeatureFunctionalClass
SyntaxPlain functionES6 class extending React.Component
StateuseState hookthis.state + setState
LifecycleuseEffectcomponentDidMount etc.
this keywordNot usedRequired, needs binding
BoilerplateLessMore
Modern ReactRecommendedLegacy
Hooks supportYesNo

Interview Point

Since React 16.8, functional components can do everything class components can. Error boundaries are the one exception — they still require a class (or a library like react-error-boundary).


5. Props

Props are read-only inputs passed from a parent to a child.

jsx
function Profile({ name, role }) {
  return <p>{name} — {role}</p>;
}

<Profile name="Dipak" role="Frontend Dev" />

Props Are Immutable

jsx
function Bad({ name }) {
  name = "Rahul"; // works locally, but never do this
  return <p>{name}</p>;
}

Never mutate props. Data flows down. To change parent data, the parent passes a callback down.

jsx
function Parent() {
  const [count, setCount] = useState(0);
  return <Child onIncrement={() => setCount(count + 1)} />;
}

children Prop

jsx
function Card({ children }) {
  return <div className="card">{children}</div>;
}

<Card>
  <h2>Title</h2>
  <p>Body</p>
</Card>

Default Props

jsx
function Button({ variant = "primary", children }) {
  return <button className={variant}>{children}</button>;
}

Default parameters replace the old Button.defaultProps, which is deprecated for function components in React 19.


6. State vs Props

PropsState
OwnerParentThe component itself
MutableNoYes (via setter)
PurposeConfigure a componentTrack changing data
Triggers re-renderYes (when parent re-renders)Yes
Passed downYesOnly as props to children

Interview Point

A one-liner that works: "Props are arguments to a function. State is a variable inside the function that survives between calls."


7. Keys in Lists

Keys help React identify which list items changed, were added or removed.

jsx
{users.map((user) => (
  <li key={user.id}>{user.name}</li>
))}

Why Index as Key Is Bad

jsx
{users.map((user, index) => (
  <li key={index}>{user.name}</li> // avoid
))}

If you delete the first item, every index shifts. React reuses the wrong DOM node, and any internal state (like an <input> value) attaches to the wrong row.

Rules

  • Keys must be unique among siblings (not globally)
  • Keys must be stable across renders
  • Never use Math.random() as a key — it forces a full remount every render
  • Index is acceptable only for a static list that never reorders, filters or deletes

Interview Point

Keys are a hint to React's diffing algorithm. Without them React falls back to comparing by position, which causes wrong-state bugs, not just slow renders.


8. Controlled vs Uncontrolled Components

Controlled

React state is the single source of truth.

jsx
function Form() {
  const [email, setEmail] = useState("");

  return (
    <input
      value={email}
      onChange={(e) => setEmail(e.target.value)}
    />
  );
}

Uncontrolled

The DOM holds the value, and you read it with a ref.

jsx
function Form() {
  const inputRef = useRef();

  const handleSubmit = () => {
    console.log(inputRef.current.value);
  };

  return <input ref={inputRef} defaultValue="" />;
}

Comparison

ControlledUncontrolled
Source of truthReact stateDOM
Value propvaluedefaultValue
Re-renders on typingYesNo
Instant validationEasyHard
File inputNot possibleRequired

Interview Point

Controlled is the default recommendation. Use uncontrolled for file inputs, or for large forms where per-keystroke re-renders hurt (this is why react-hook-form is uncontrolled by design).


9. Conditional Rendering

if / else

jsx
function Status({ isLoggedIn }) {
  if (isLoggedIn) return <Dashboard />;
  return <Login />;
}

Ternary

jsx
<div>{isLoggedIn ? <Dashboard /> : <Login />}</div>

Logical AND

jsx
<div>{hasError && <p className="error">Something went wrong</p>}</div>

The && Trap

jsx
{items.length && <List items={items} />}

If items.length is 0, React renders the literal 0 on screen. Fix with an explicit boolean:

jsx
{items.length > 0 && <List items={items} />}

Switching Component Pattern

jsx
const PAGES = {
  home: Home,
  about: About,
  contact: Contact,
};

function Page({ name }) {
  const Component = PAGES[name] || NotFound;
  return <Component />;
}

A lookup object beats a long if/else chain and is a common "how would you build a switching component" answer.


10. Higher Order Components (HOC)

A HOC is a function that takes a component and returns a new component. It is a pattern, not a React API.

jsx
function withLoading(Component) {
  return function WithLoading({ isLoading, ...props }) {
    if (isLoading) return <Spinner />;
    return <Component {...props} />;
  };
}

const UserListWithLoading = withLoading(UserList);

Common Real HOCs

  • React.memo
  • connect() from React Redux
  • withRouter (React Router v5)

Problems with HOCs

  • Wrapper hell in DevTools
  • Prop name collisions
  • Hard to trace where a prop came from

Interview Point

Custom hooks have largely replaced HOCs for logic reuse. HOCs are still useful when you need to wrap or replace the rendered output, not just share logic.


11. Render Props

Sharing logic by passing a function as a prop.

jsx
function MouseTracker({ render }) {
  const [pos, setPos] = useState({ x: 0, y: 0 });

  return (
    <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
      {render(pos)}
    </div>
  );
}

<MouseTracker render={({ x, y }) => <p>{x}, {y}</p>} />

Also largely replaced by custom hooks, but still asked in interviews as "name the patterns for code reuse in React": HOC, Render Props, Custom Hooks.


12. Error Boundaries

An error boundary catches JavaScript errors in its child tree, logs them, and shows a fallback UI instead of a blank screen.

jsx
class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    console.error(error, info);
  }

  render() {
    if (this.state.hasError) return <h2>Something went wrong.</h2>;
    return this.props.children;
  }
}

What Error Boundaries Do NOT Catch

  • Event handler errors (use try/catch)
  • Async code (setTimeout, promises)
  • Server-side rendering
  • Errors thrown inside the boundary itself

Interview Point

Error boundaries must be class components — there is no hook equivalent. In practice most teams use the react-error-boundary package, which wraps the class for you.


13. React Portals

A portal renders a child into a DOM node outside the parent component's DOM hierarchy, while keeping it in the React tree.

jsx
import { createPortal } from "react-dom";

function Modal({ children }) {
  return createPortal(children, document.getElementById("modal-root"));
}

Why

Modals, tooltips and dropdowns break when a parent has overflow: hidden or a z-index stacking context. A portal escapes that.

Interview Point

Events still bubble through the React tree, not the DOM tree. A click inside a portal fires the onClick of its React parent, even though the DOM nodes are far apart.


14. Strict Mode

jsx
<React.StrictMode>
  <App />
</React.StrictMode>

Strict Mode is a development-only tool. It:

  • Double-invokes render, state updaters and effects to expose impure code
  • Warns about deprecated APIs and legacy string refs
  • Since React 18, mounts → unmounts → remounts each component once

Interview Point

"My useEffect runs twice" is almost always Strict Mode in development. It is intentional — it surfaces missing cleanup functions. It does not happen in production builds.


15. Component Lifecycle

The Three Phases

PhaseClass methodHook equivalent
Mountingconstructor, render, componentDidMountuseState init, useEffect(fn, [])
UpdatingshouldComponentUpdate, render, componentDidUpdateReact.memo, useEffect(fn, [deps])
UnmountingcomponentWillUnmountcleanup returned from useEffect
ErrorgetDerivedStateFromError, componentDidCatchclass only

Hook Equivalent Of All Three

jsx
useEffect(() => {
  // componentDidMount + componentDidUpdate
  const id = setInterval(tick, 1000);

  return () => {
    // componentWillUnmount
    clearInterval(id);
  };
}, [tick]);

Interview Point

useEffect is not an exact lifecycle mapping. It is a synchronisation tool: "keep this external system in sync with these values". Interviewers like candidates who say this instead of reciting a method table.


16. Types of Side Effects

TypeMeaningHook
Cleanup-lessFire and forget — logging, analyticsuseEffect
With cleanupSubscriptions, timers, listenersuseEffect + return function
Layout effectsMeasuring DOM before paintuseLayoutEffect
jsx
// No cleanup
useEffect(() => {
  document.title = `${count} unread`;
}, [count]);

// With cleanup
useEffect(() => {
  const onResize = () => setWidth(window.innerWidth);
  window.addEventListener("resize", onResize);
  return () => window.removeEventListener("resize", onResize);
}, []);

Missing the cleanup causes memory leaks and duplicate listeners — a very common interview follow-up.

© 2025 DDocs · Dipak's Documentation Guide