Frontend Interview Questions (Part 7)

React re-rendering, optimization, and performance concepts

By Hank Kim

Frontend Interview Questions (Part 7)

React re-rendering, optimization, and performance concepts

Frontend Interview Questions (Part 7)

Question 1. When does React re-render?

  • Re-renders happen when subscribed values change.
  • Triggers:

    • state updates (useState, useReducer)
    • Parent component re-renders
    • Props change
    • Context value changes
    • External store (Redux, Zustand, etc.) updates

Notes

  • Props are read-only. If parent re-renders, child re-renders unless wrapped in React.memo.
  • React.memo skips re-render if props are shallow-equal.
  • Don’t copy props into state (can cause inconsistencies).

Question 2. What is the DOM?

  • Document Object Model → Browser API representing an HTML/XML document as a tree structure.
  • Nodes form a hierarchy: parent/child/sibling.
  • Allows JS to manipulate content (add/remove/update elements, attach event handlers).
  • Without DOM, static HTML cannot be dynamically updated.

Question 3. Difference between any and unknown in TypeScript?

  • Both are top types (can hold any value).
Feature any unknown
Type checking Disabled (unsafe) Required before use
Usage No compiler checks Forces narrowing via type guards
Example let x: any; x.trim(); let x: unknown; x.trim(); ❌ (error)
  • Use unknown when type is uncertain at runtime (e.g., catch (err: unknown)).
  • Narrow with type guards (typeof, instanceof).
  • any = unsafe bypass, unknown = safer but requires explicit checks.

Question 4. What is a Transpiler?

  • Tool that converts code into another form of JavaScript syntax or another high-level language.
  • Examples: Babel, SWC, esbuild, TypeScript Compiler.
  • Needed because:

    • Browsers support different JS versions.
    • JSX and TypeScript are not native JS.

Transpiler vs Polyfill

  • Transpiler: build-time syntax conversion (e.g., ()=>{}function(){}).
  • Polyfill: runtime feature implementation (e.g., Promise in old browsers).
  • Example: Babel transpiles async/await, core-js polyfills Promise.

Question 5. What is Base64, and why use it?

  • Encoding binary → ASCII using 64 characters (A-Z, a-z, 0-9, +, /).
  • Expands data size by ~33%.

Uses

  • Embed small images/icons inline in HTML/CSS (avoid HTTP requests).
  • Encode JWT header & payload (safe for URLs/headers).
  • Ensure binary data is safely transmitted as text.

Notes

  • JWT uses URL-safe Base64 (no +, /, =).
  • Drawback: large images become bloated, caching less efficient.

Question 6. Arrow Functions vs Function Declarations

  • Arrow Functions

    • No arguments object (use rest params).
    • Lexical this → inherits from enclosing scope.
    • Cannot be used as constructors.
    • Shorter syntax, implicit return.
  • Function Declarations

    • Hoisted (usable before definition).
    • Own this (depends on call site).
    • Access to arguments object.
    • Can be constructors.

👉 Arrow functions improve predictability of this, useful for callbacks.


Question 7. What is useReducer?

  • Alternative to useState for complex state logic.
  • Good for centralized state updates.
function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      return state;
  }
}
const [state, dispatch] = useReducer(reducer, { count: 0 });
  • Benefits: clearer when state transitions are complex, or when multiple values must update together.

Question 8. Why use Custom Hooks?

  • Encapsulate logic with lifecycle + state.
  • Reuse across components.
  • Separate view/UI from business logic.
  • Example: useUser() for data fetching → component only renders UI.

Question 9. Component Design Principles

  1. Single Responsibility → one component = one purpose.
  2. Reusable UI elements → extract buttons, inputs, etc.
  3. Separate view from logic → keep components pure, move logic into custom hooks.

    // ❌ Logic inside component
    const User = () => {
      const [u, setU] = useState();
      useEffect(()=>{fetch(...).then(setU)},[]);
      return <p>{u?.name}</p>;
    };
    // ✅ Separated with hook
    function useUser() { ... }
    const User = () => {
      const u = useUser();
      return <p>{u?.name}</p>;
    };
    
  4. Pure rendering → given props in → predictable UI out.