Top 45 React Interview Questions and Answers

Fernando DoglioFernando Doglio

React interview questions and answers

Landing your dream React role requires that you showcase your experience and understanding of the library. And if you’re actually a hiring manager looking to find the best way to test the knowledge of your candidates, finding the right set of questions is crucial to the success of your search.

Lucky for you, this isn't just another Q&A list; it's your comprehensive guide, designed to arm you with the knowledge to confidently discuss everything from functional components to the intricacies of React Server Components.

Grab a cup of your favorite hot drink, and get ready to explore the core concepts, common challenges, and cutting-edge features that define modern React development.

TL;DR:

  • Learn 45 common React interview questions

  • Test yourself with flashcards

  • Review key React concepts, like components and hooks

  • Strengthen understanding of both basic and advanced topics

  • Explore the React roadmap to continue mastering the library

To go even further, you can use the roadmap AI tutor to get help and ask questions, understand concepts, track your progress, and receive personalized learning advice.

Getting Ready for Your React Deep Dive

But before we get to the actual list of questions, let’s talk about the interview itself and how you can prepare for it.

  • Deconstruct the Core: You wouldn't build a complex React application without understanding its fundamental React features. Similarly, for your interview, grasp the "whys" and use them. Why unidirectional data flow? What problem did hooks in React solve? Why is component-based architecture so powerful for building user interfaces?

  • Code It Out: Reading about controlled components or asynchronous data loading is one thing; actually implementing them is another. Fire up your favorite IDE, build small function app examples that demonstrate state and lifecycle methods, how to pass data between parent and children components, or even a basic custom hook.

  • Debug Your Experience: Every developer has faced bugs. Instead of just listing projects, practice articulating the challenges you encountered, especially those related to React components, complex state management, or optimizing rendering components. How did you identify the issue? What patterns did you use to debug? Showing your problem-solving process is as crucial as knowing the answer.

  • Interactive Learning: Not everyone realizes this, but interviews go both ways. Prepare thoughtful questions about the team's tech stack (do they lean on Context API or a full-blown state management library?), their approach to testing, or how they handle server-side rendering. It shows you're not just looking for a job, but for the right environment to grow your React skills.

Test yourself with Flashcards

You can either use these flashcards or jump to the questions list section below to see them in a list format.

0 / 45
Knew0 ItemsLearnt0 ItemsSkipped0 Items
React Interview Questions: The Beginner's Ascent

What is React, and what problem does it solve in web development?

React is a free and open-source front-end JavaScript library for building user interfaces or UI components. It allows developers to create large web applications that can change data without reloading the page. It solves the problem of efficiently updating the DOM and creating interactive, scalable UIs by using a component-based architecture and a Virtual DOM.

Questions List

If you prefer to see the questions in a list format, you can find them below.

React Interview Questions: The Beginner's Ascent

What is React, and what problem does it solve in web development?

React is a free and open-source front-end JavaScript library for building user interfaces or UI components. It allows developers to create large web applications that can change data without reloading the page. It solves the problem of efficiently updating the DOM and creating interactive, scalable UIs by using a component-based architecture and a Virtual DOM.

Explain the concept of the Virtual DOM in React. How does it improve performance compared to the Actual DOM?

The Virtual DOM is a lightweight, in-memory representation of the Actual DOM (the browser's Document Object Model). When React state or props change, React first updates the Virtual DOM. It then efficiently compares the updated Virtual DOM with the previous version (a process called "diffing") to figure out the minimal set of changes needed. Finally, it applies only those necessary changes to the Actual DOM. This improves performance because directly manipulating the Actual DOM is slow and expensive; the Virtual DOM minimizes these operations

What are React Components? Why are they considered the building blocks of a React application?

React Components are independent, reusable pieces of UI. They are like JavaScript functions or classes that optionally accept inputs (called "props") and return React elements describing what should appear on the screen. They are the building blocks because they allow you to break down complex user interfaces into smaller, manageable, and reusable components, promoting modularity and maintainability in a React application

Differentiate between functional components and class components in React. When would you use one over the other?

Functional Components: These are JavaScript functions that return JSX. They are simpler to write, often used for presentational (or "stateless") components, and became the preferred way to write React components with the introduction of React Hooks, which allow them to manage state and perform side effects.

Class Components: These are ES6 classes that extend React.Component and require a render() method to return JSX. They historically managed React state and handled component lifecycle through lifecycle methods.

When to use: With the advent of React Hooks, functional components are now generally preferred for new development as they offer a more concise and often more readable way to manage component logic and React state. Class components are still found in older codebases or specific scenarios where their lifecycle methods might be more intuitive (though hooks often provide equivalent functionality).

What is JSX? Explain its purpose in React.

JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write HTML-like code directly within your JavaScript files. Its purpose in React is to describe the structure of the UI. It makes writing and understanding the UI more intuitive by closely resembling HTML, while still allowing the full power of JavaScript for dynamic content. Behind the scenes, JSX gets "transpiled" into regular JavaScript function calls (e.g., React.createElement()).

How do you create a basic React Element?

You typically create a React Element using JSX.

jsx
// Using JSX (most common)const element = <h1>Hello, React!</h1>;// Without JSX (less common, but shows what JSX compiles to)// const element = React.createElement('h1', null, 'Hello, React!');

What is the purpose of render() method in class components?

The render() method is a required method in class components. Its purpose is to return the React elements (JSX) that represent the UI the component wants to display. It's a pure function, meaning it should not modify state or interact with the DOM directly.

How do you embed expressions in JSX?

You embed JavaScript expressions in JSX by enclosing them in curly braces {}. This allows you to dynamically inject variables, function calls, or other JavaScript expressions into your UI.

jsx
const name = "Alice";const element = <h1>Hello, {name}!</h1>;const sum = 5 + 3;const resultElement = <p>The sum is: {sum}</p>;

Explain the concept of "props" in React. How do you pass data from a parent component to a child component using props?

"Props" (short for "properties") are read-only inputs that components receive from their parent component. They allow you to pass data and configuration down the component tree.

You pass data using props by adding attributes to the child component when you render it in the parent. The child component then receives these attributes as an object in its props.

js
// ParentComponent.jsfunction ParentComponent() {  const message = "Hello from parent!";  return <ChildComponent text={message} />;}// ChildComponent.jsfunction ChildComponent(props) {  return <p>{props.text}</p>;}

What is React State? How is it different from props?

React State is an object that holds data that can change over time within a component. When a component's state changes, React re-renders the component and its children to reflect the new state. It's private to the component where it's defined and allows components to be dynamic and interactive.

Difference from Props:

  • Props: Passed down from a parent component; read-only (immutable) for the receiving component.

  • State: Managed within a component; mutable and can be changed by the component itself.

How do you manage a component's state in a class component?

In a class component, you manage the component's state by initializing it in the constructor as an object assigned to this.state. You update it using this.setState() method, which merges the new state into the current state and triggers a re-render.

js
class Counter extends React.Component {  constructor(props) {    super(props);    this.state = { count: 0 };  }  increment = () => {    this.setState({ count: this.state.count + 1 });  };  render() {    return (      <div>        <p>Count: {this.state.count}</p>        <button onClick={this.increment}>Increment</button>      </div>    );  }}

How do you manage a component's state in a functional setting?

In a functional component, you manage the component's state using the useState React Hook. useState returns an array with two elements: the current state value and a function to update it.

js
import React, { useState } from 'react';function Counter() {  const [count, setCount] = useState(0);  const increment = () => {    setCount(count + 1);  };  return (    <div>      <p>Count: {count}</p>      <button onClick={increment}>Increment</button>    </div>  );}

Explain unidirectional data flow in React. Why is it important?

Unidirectional data flow means that data in a React application moves in a single direction: from parent components down to their children via props. Child components cannot directly modify the data received through props; if they need to change data, they typically call a function (passed down as a prop) that lives in the parent, which then updates its own state, triggering a re-render.

Importance: It makes the application's data flow predictable and easier to understand, debug, and maintain. By clearly defining how data flows, it reduces the complexity of complex state management and helps prevent unexpected side effects.

What is the significance of keys when rendering multiple components in a list?

Keys are special string attributes you need to include when creating lists of multiple elements or components. Their significance lies in helping React efficiently identify which items have changed, been added, or been removed in a list. When a list is re-rendered, React uses keys to match list items in the old tree with list items in the new tree. Without unique and stable keys, React's reconciliation process can be inefficient, leading to performance issues and potential bugs (e.g., incorrect state being applied to the wrong items).

How do you handle events in React? Provide an example.

You handle events in React by passing a function as the event handler. Event handlers are typically named using camelCase (e.g., onClick, onChange), and the function is passed directly as the value of the prop.

js
function MyButton() {  const handleClick = () => {    alert('Button clicked!');  };  return (    <button onClick={handleClick}>Click Me</button>  );}

React's event system creates "synthetic events" which are cross-browser wrappers around the browser's native event system.

What is the purpose of setState() in class components? Why is it asynchronous?

The purpose of setState() in class components is to update the component's state and trigger a re-render of the component and its children.

It is asynchronous because React batches multiple setState() calls into a single update for performance optimization. This prevents unnecessary re-renders that would occur if each state update triggered an immediate DOM update. Because of this, you should not rely on this.state it immediately after calling setState(); if you need to perform actions after the state has definitely updated, use the callback function as a second argument to setState() or componentDidUpdate.

What are the benefits of using reusable components?

  • Modularity: Breaking down the UI into smaller, independent units.

  • Maintainability: Easier to understand, debug, and update specific parts of the UI.

  • Consistency: Ensures a consistent look and feel across the application.

  • Efficiency: Reduces code duplication and speeds up development.

  • Testability: Individual React components are easier to test React components in isolation.

What is the ReactDOM.render() method used for?

ReactDOM.render() is the entry point for a React application into the DOM. It's used to render a React element or React component into a specific DOM element in your HTML page. In modern React (React 18+), it has largely been replaced by createRoot() for better concurrent features.

Note: For modern React 18+, the equivalent is ReactDOM.createRoot(document.getElementById('root')).render(<App />);

How do you include external CSS files in a React App?

You can include external CSS files in a React App by importing them directly into your JavaScript or JSX files. Build tools like Create React App or Webpack will handle bundling them.

js
// In App.jsimport './App.css';function App() {  // ...}

Other methods include CSS Modules, Styled Components, or inline styles.

How do you conditionally render components in React?

You can conditionally render components in React using standard JavaScript conditional operators or logical operators within your JSX:

  • if statements (outside JSX):

js
function Greeting({ isLoggedIn }) {  if (isLoggedIn) {    return <UserGreeting />;  }  return <GuestGreeting />;}
  • Ternary operator (condition ? true : false):

js
function Greeting({ isLoggedIn }) {  return isLoggedIn ? <UserGreeting /> : <GuestGreeting />;}
  • Logical && operator (for rendering something or nothing):

js
function Mailbox({ unreadMessages }) {  return (    <div>      <h1>Hello!</h1>      {unreadMessages.length > 0 &&        <h2>You have {unreadMessages.length} unread messages.</h2>      }    </div>  );}

Explain what happens during the mounting phase of a component lifecycle.

The mounting phase is the first phase in a component's lifecycle, where an instance of the component is created and inserted into the DOM.

For Class Components: During mounting, methods like constructor(), static getDerivedStateFromProps(), render(), and componentDidMount() are called in order. componentDidMount() is particularly important as it's where you'd typically perform initial data fetching or DOM manipulations after the component is rendered for the first time.

For Functional Components: The mounting phase involves the initial execution of the React function component’s body and any useState initializations. The useEffect hook with an empty dependency array ([]) behaves similarly to componentDidMount, running only once after the initial render.

React Interview Questions: The Advanced Ascent

Name and explain some commonly used React Hooks.

  • useState: Allows React function components to add state. It returns a stateful value and a function to update it. (e.g., const [count, setCount] = useState(0);)

  • useEffect: Allows functional components to perform side effects (like data fetching, subscriptions, or manually changing the DOM) after render. It runs after every render by default, but can be controlled with a dependency array.

  • useContext: Allows functional components to subscribe to React context, making it easier to pass information through the component tree without prop-drilling.

  • useRef: Returns a mutable ref object whose .current property is initialized to the passed argument. It's often used to access DOM elements directly or persist values across renders without causing re-renders.

  • useCallback: Returns a memoized callback function. This prevents unnecessary re-creation of functions on every render, which is useful for optimizing components that rely on reference equality to prevent unnecessary re-renders.

  • useMemo: Returns a memoized value. This prevents expensive computations from running on every render by only re-computing the value when its dependencies change.

  • useReducer: An alternative to useState for complex state management where state logic involves multiple sub-values or the next state depends on the previous one. It's similar to Redux's reducer pattern.

How does useState work, and what problem does it solve?

useState is a React Hook that lets you add state to functional components. When called, it returns an array containing two items: the current state value and a function to update that value. When the update function is called, React re-renders the functional component with the new state value.

It solves the problem of needing to use class components just to manage a component's state. Before useState, functional components were "stateless" (also called stateless components), meaning they could only receive data via props and couldn't hold internal, mutable data that triggered re-renders. useState brings the power of managing React state to functional components, making them equally capable of handling dynamic and interactive UIs.

Explain the useEffect hook. What are its common use cases, and how do you handle cleanup?

The useEffect hook allows components to perform "side effects" (operations that interact with the outside world, like data fetching, subscriptions, timers, or direct DOM manipulation) after every render. It takes two arguments: a function containing the effect logic and an optional dependency array.

Common Use Cases:

  • Asynchronous data loading (e.g., fetching data from an API on initial load time or when a prop changes).

  • Setting up subscriptions (e.g., to a WebSocket or an external store).

  • Manually changing the DOM (e.g., updating the document title).

  • Timers (e.g., setTimeout, setInterval).

Handling Cleanup: If your effect performs an operation that requires cleanup (like unsubscribing or clearing a timer), the function passed to useEffect can return another function. This returned function will be executed by React when the component unmounts or before the effect runs again due to dependency changes.

When would you use useContext? How does it help in manage state across the component tree?

You would use useContext when you need to pass data that is considered "global" to a subsection of the component hierarchy, without having to manually pass props down through every level (a problem known as "prop drilling"). Examples include user authentication status, theme preferences (light/dark mode), or locale settings.

It helps manage state by allowing components in React to consume a context value directly from the nearest Context.Provider above it in the tree, regardless of how many intermediate components there are. This centralizes the data and makes it available to any consumer without explicit prop passing, simplifying data flow for widely used data.

What is the purpose of useReducer? How is it different from useState for complex state management?

The purpose of useReducer is to provide an alternative to useState for complex state management, especially when state logic involves multiple sub-values, or when the next state depends on the previous one. It's often preferred for states that are updated in a more complex way, similar to how Redux manages state with a reducer function.

Differences from useState:

  • Complexity:useState is great for simple state values (numbers, strings, booleans, simple objects). useReducer is better for more intricate complex state logic, such as when state updates involve multiple related values or require specific sequences of operations.

  • Logic Separation:useReducer separates the state update logic (the reducer function) from the component itself, making the component logic cleaner and often more testable.

  • Batched Updates:useReducer automatically provides a stable dispatch function, which is useful when passing dispatch down to optimized components underneath the current one to prevent unnecessary re-renders, as dispatch's reference never changes.

Explain the concept of the component lifecycle in class components. Name and describe the main lifecycle methods.

The component lifecycle describes the various phases a component goes through from its creation to its removal from the DOM. In class components, these phases are managed by special lifecycle methods that React calls at specific points.

Main Lifecycle Methods:

  • Mounting (Component creation and insertion into DOM):

    • constructor(): Initialises state and binds methods.

    • static getDerivedStateFromProps(props, state): Updates state based on prop changes.

    • render(): Returns JSX to render to the DOM.

    • componentDidMount(): Called immediately after the component is mounted (inserted into the DOM). Good for asynchronous data loading, subscriptions, or direct DOM interactions.

  • Updating (Component re-render due to prop or state changes):

    • static getDerivedStateFromProps(props, state): (Also called here)

    • shouldComponentUpdate(nextProps, nextState): (Optional) Can prevent unnecessary re-renders if it returns false. Used for performance optimization.

    • render(): Re-renders JSX.

    • getSnapshotBeforeUpdate(prevProps, prevState): Called right before the changes from the Virtual DOM are committed to the Actual DOM. Useful for capturing scroll position.

    • componentDidUpdate(prevProps, prevState, snapshot): Called after the component has updated. Good for data fetching based on prop/state changes.

  • Unmounting (Component removal from DOM):

    • componentWillUnmount(): Called right before the component is unmounted and destroyed. Good for cleanup (e.g., unsubscribing, clearing timers).

  • Error Handling (Catching errors in children components):

    • static getDerivedStateFromError(error): Renders fallback UI after an error.

    • componentDidCatch(error, info): Logs error information.

How do lifecycle methods in class components map to React hooks in functional components?

While not a direct one-to-one mapping, React Hooks provide equivalent functionalities:

  • constructor() / useState initialization: Initial state in useState.

  • componentDidMount(): useEffect with an empty dependency array ([]).

  • componentDidUpdate(): useEffect with a dependency array containing the values that, when changed, should trigger the effect.

  • componentWillUnmount(): The cleanup function returned from useEffect.

  • shouldComponentUpdate(): React.memo for components or useMemo/useCallback for specific values/functions.

  • getDerivedStateFromProps(): Often handled by useEffect or useMemo depending on the use case.

  • componentDidCatch(): Error Boundaries (still class components for now).

What are Higher-Order Components (HOCs)? Provide an example of where you might use one.

Higher-Order Components (HOCs) are an advanced technique in React for reusing component logic. A HOC is a function that takes a component as an argument and returns a new component with enhanced props or behavior. They're a pattern derived from higher-order functions in functional programming.

Example Use Case: A common use case is for providing common data or functionality to multiple components without duplicating code, such as withAuth (adding authentication status), withLoading (showing a loading spinner), or withLogging (logging component lifecycle events).

js
// Example: withLoading HOCfunction withLoading(Component) {  return function WithLoadingComponent({ isLoading, ...props }) {    if (isLoading) {      return <p>Loading...</p>;    }    return <Component {...props} />;  };}// Usage:const MyComponentWithLoading = withLoading(MyDataDisplayComponent);// <MyComponentWithLoading isLoading={true} data={...} />

What is the Context API? When would you use it instead of prop drilling for data flow?

The Context API is a feature in React that allows you to pass data through the component tree without having to pass props down manually at every level. It consists of React.createContext, Provider, and Consumer (or useContext hook).

You would use it instead of "prop drilling" (passing a prop through many intermediate children components that don't directly use the prop) when:

  • The data is genuinely "global" or needed by many components in React at different levels of the tree (e.g., themes, user info, language preferences).

  • The data flow becomes too cumbersome and verbose due to many layers of prop passing.

For complex state management that involves frequent updates or very large applications, a dedicated state management library (like Redux or Zustand) might still be more suitable, but this API is excellent for a simpler global state.

Explain the concept of Server-Side Rendering (SSR) in React. What are its benefits and drawbacks?

Server-Side Rendering (SSR) is a technique where the initial HTML of a React application is generated on the server and then sent to the client. Once the HTML arrives, the JavaScript bundle is downloaded and "hydrates" the static HTML, making it interactive.

Benefits:

  • Improved Initial Load Time: Users see content much faster because the HTML is immediately available.

  • Better SEO: Search engine crawlers can easily index the content, as the full HTML is present on the first request.

  • Better Performance on Slower Networks/Devices: The user gets visual content sooner, improving perceived performance.

Drawbacks:

  • Increased Server Load: The server has to do more work to render the application.

  • Complexity: Setting up and managing SSR can be more complex than a purely client-side rendered application.

  • Larger Server Bundle: The server might need to ship a larger JavaScript bundle to handle the rendering.

What is React.memo()? How does it help optimize child components?

React.memo() is a Higher-Order Component (HOC) that "memoizes" a component. It helps optimize optimized child components by preventing them from re-rendering if their props have not shallowly changed.

When a parent component re-renders, its children typically re-render too. React.memo() provides a performance boost by skipping the re-rendering of a component if its props are the same as the previous render. It performs a shallow comparison of props. If props are complex objects or functions, you might need to combine React.memo with useCallback or useMemo for effective optimization.

Explain the purpose of useCallback and useMemo hooks. When should you use them?

useCallback:

  • Purpose: Returns a memoized version of a callback function. It only re-creates the function if one of its dependencies has changed.

  • When to use: Primarily for performance optimization to prevent unnecessary re-renders of child components that receive functions as props. If a child component is wrapped in React.memo, passing it a new function reference on every parent re-render would cause it to re-render unnecessarily. useCallback ensures the function reference remains stable unless its dependencies change.

useMemo:

  • Purpose: Returns a memoized value. It only re-computes the value if one of its dependencies has changed.

  • When to use: For performance optimization to avoid expensive computations on every render. If you have a calculation that takes time and its result is only dependent on specific inputs, useMemo can store the result and only re-calculate when those inputs change.

General Rule: Use useCallback for functions and useMemo for values, but only when profiling indicates a performance bottleneck, as they introduce their own overhead.

How do you handle async data loading in a React application? Discuss different approaches.

There are several common approaches to handling asynchronous data loading in a React application:

useEffect hook: The most common approach. You perform the data fetch inside useEffect, and manage loading, error, and data states using useState.

js
useEffect(() => {  const fetchData = async () => {    setLoading(true);    try {      const response = await fetch('/api/data');      const data = await response.json();      setData(data);    } catch (error) {      setError(error);    } finally {      setLoading(false);    }  };  fetchData();}, []);

Custom Hooks: Encapsulate data fetching logic into a reusable components custom hook (e.g., useFetch). This promotes code reuse and separation of concerns.

Dedicated Data Fetching Libraries: Libraries like React Query (TanStack Query), SWR, or Apollo Client (for GraphQL) provide powerful features like caching, revalidation, optimistic updates, and error handling, simplifying asynchronous data loading for complex scenarios.

componentDidMount/componentDidUpdate (for class components): In class components, data fetching is typically done in componentDidMount for initial load and componentDidUpdate if fetching depends on props/state changes.

What are Pure Components in React? How do they differ from regular class components?

PureComponent is a base class that class components can extend instead of React.Component. The primary difference is that PureComponent automatically implements shouldComponentUpdate() with a shallow prop and state comparison.

How they differ:

  • A regular React.Component will re-render whenever its parent re-renders, or its state/props change, by default.

  • A PureComponent will not re-render if its props and state have not shallowly changed.

Caveats: Shallow comparison means it won't detect changes within nested objects or arrays, which can lead to bugs if not handled carefully (e.g., by creating new objects/arrays when they change). React.memo() is the functional components equivalent.

Explain Error Boundaries in React. How do they work, and what problem do they solve?

Error Boundaries are class components (as of now, hooks don't exist for this) that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of crashing the entire React application.

How they work: You wrap a part of your UI with an Error Boundary component. If any error occurs within the components rendered inside the boundary (including nested ones), the Error Boundary will "catch" it using lifecycle methods like static getDerivedStateFromError() (to render fallback UI) and componentDidCatch() (to log error information).

Problem they solve: They prevent the entire React app from crashing and displaying a blank screen due to an uncaught JavaScript error in one part of the UI. Instead, they allow you to gracefully handle errors, provide a better user experience, and log errors for debugging.

What is React Router? How does it enable navigation in a Single Page Application?

React Router is a popular library for client-side routing in React applications. It enables navigation in a Single Page Application (SPA) by allowing different components to be rendered based on the URL, without requiring a full page reload from the server.

It works by:

  • Listening for URL Changes: It monitors changes in the browser's URL (using the History API or hash fragments).

  • Mapping URLs to Components: It defines routes that map specific URL paths to corresponding React components.

  • Rendering Components: When the URL matches a defined route, React Router renders the associated React component in the designated area (often within a <Routes> or <Switch> component).

  • No Full Reloads: It intercepts navigation events (like clicking <Link> components) and prevents the default browser behavior of requesting a new page from the server, thus keeping the application a single page.

How do you pass parameters or dynamic data using React Router?

You can pass parameters or dynamic data using React Router in several ways:

URL Parameters: Define a dynamic segment in your route path (e.g., /users/:id). The parameter value (e.g., 123 for /users/123) can then be accessed using the useParams() hook (in functional components) or this.props.match.params (in class components).

js
// Route definition<Route path="/users/:userId" element={<UserProfile />} />// UserProfile componentimport { useParams } from 'react-router-dom';function UserProfile() {  const { userId } = useParams();  return <h1>User ID: {userId}</h1>;}

Query Parameters: Appending data to the URL after a ? (e.g., /search?query=react). These are accessed using the useSearchParams() hook.

State (via Link or Maps): You can pass an arbitrary state object when navigating programmatically using the state prop of a <Link> component or the Maps function, which can be accessed via useLocation() hook.

What are React Portals? When would you use them?

React Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent React component. Normally, a child component's JSX is rendered as a child of its parent's DOM node. React Portals break this rule.

When to use them: You would use React Portals when you need to render content that visually "escapes" the parent's container, especially regarding CSS stacking contexts (z-index) or overflow issues. Common use cases include:

  • Modals/Dialogs: To ensure they overlay all other content.

  • Tooltips/Popovers: To prevent them from being clipped by their parent's overflow style.

  • Loaders/Spinners: To display them globally.

  • Third-party widgets: To inject content into a specific, non-React controlled DOM element.

React Interview Questions: The Pro's Pinnacle

What are React Server Components (RSCs), and how do they differ fundamentally from traditional React Client Components?

React Server Components (RSCs) are a new paradigm in React that allows components to be rendered on the server, resulting in zero-bundle-size client-side JavaScript. They are distinct from traditional SSR because they are designed to be streamed to the client incrementally, and they don't produce full HTML directly; instead, they produce a special "RSC Payload" that React on the client uses to update the DOM.

Fundamental Differences:

RSCs

Client Components

Execution Environment:

Run exclusively on the server (or at build time). They never run in the browser.

Run in the browser.

Bundle Size:

Do not contribute to the client-side JavaScript bundle size. Their code never leaves the server.

Are part of the client-side JavaScript bundle.

State & Effects:

Cannot use state (useState) or React Hooks like useEffect, as they don't have a component lifecycle in the browser. They are "stateful" in the sense that they can hold server-side data, but not interactive client-side state.

Can use all React Hooks including useState and useEffect.

Data Access:

Can directly access server-side resources like databases, file systems, or private API keys without exposing them to the client. This simplifies asynchronous data loading.

Must fetch data via API endpoints over HTTP, as they don't have direct server access.

Interactivity:

Purely render UI. They cannot handle user interactions (e.g., onClick).

Explain how the reconciliation algorithm works in React's Virtual DOM.

The reconciliation algorithm is the process React uses to efficiently update the Actual DOM. It's at the core of the Virtual DOM concept.

Steps:

  1. New Tree Generation: When state or props change, React creates a new Virtual DOM tree representing the updated UI.

  2. Diffing: React then "diffs" (compares) this new Virtual DOM tree with the previous Virtual DOM tree. This diffing process is optimized with two main heuristics:

    • Two elements of different types will produce different trees: If a <div> changes to a <span>, React will tear down the old tree and build a new one from scratch.

    • The developer can hint at which child elements may be stable across different renders with a key prop: When comparing lists of multiple elements, React uses key props to efficiently identify items that have been added, removed, or reordered, minimizing DOM mutations.

  3. Batching Updates: React collects all the detected differences (the "diff") and batches them into a single update.

  4. Actual DOM Update: Finally, React applies this minimal set of changes to the Actual DOM. This minimizes expensive direct DOM manipulations, significantly improving performance.

Explain the "use client" directive. What is its purpose, and what are the implications of placing it in a file?

The "use client" directive is a convention used within the React Server Components ecosystem (specifically in frameworks like Next.js App Router).

Purpose: It's a special comment placed at the very top of a file to explicitly mark a module as a "Client Component boundary." This tells the build tools and the React runtime that this file, and any modules it imports (unless they are explicitly marked as "use server" or are Server Components themselves), should be bundled and executed on the client-side.

Implications of Placement:

  • Client-Side Execution: The code in that file and its client-side dependencies will be included in the client's JavaScript bundle.

  • Interactivity Allowed: Components within a "use client" file can use React Hooks like useState and useEffect, handle user events, and manage client-side state.

  • Server Component as Parent: A Server Component can render a Client Component. When it does, React takes care of sending the necessary client-side JavaScript to the browser.

  • Client Component as Child: A Client Component cannot render a Server Component directly (you'd need to pass a Server Component as a prop to a Client Component from a parent Server Component).

  • Boundary: It effectively creates a boundary. Any module imported below this directive is assumed to be a Client Component, while modules above it are assumed to be Server Components by default (in the App Router context).

How does React handle concurrency and scheduling updates?

React 18 introduced a new concurrent renderer, allowing React to prepare multiple versions of the UI at the same time and interrupt rendering if higher-priority updates come in. This is a fundamental shift from the previous synchronous and blocking renderer.

Key Concepts:

  • Concurrent Mode: Enables React to work on multiple tasks simultaneously. It's not "multi-threading" in the traditional sense, but about non-blocking rendering.

  • Transitions: A new concept to distinguish between urgent updates (like typing in an input) and non-urgent updates (like filtering a list). useTransition and useDeferredValue hooks allow developers to mark updates as "transitions," which are interruptible and don't block the UI.

  • Scheduler: React now has an internal scheduler that prioritizes updates. Urgent updates (e.g., keyboard input) have higher priority and can interrupt ongoing non-urgent rendering, leading to a more responsive user interfaces.

  • Fiber: The underlying reconciliation engine in React. Fiber is a re-implementation of the core algorithm designed for incremental rendering, allowing React to pause and resume work, crucial for concurrency.

This allows for smoother user experiences, especially with complex state management and frequent updates, by preventing blocking UI during expensive computations.

What are the primary benefits of using React Server Components, especially concerning performance and bundle size?

The primary benefits of React Server Components are deeply tied to performance and bundle size:

  • Zero-Bundle-Size Client JavaScript: This is the most significant benefit. Since RSCs execute entirely on the server, their code is never sent to the client. This dramatically reduces the JavaScript bundle size, leading to faster downloads and parsing, and thus a quicker initial load time.

  • Improved Data Fetching Performance: RSCs can handle asynchronous data loading directly on the server, accessing databases or internal APIs without requiring an extra network round-trip from the client. Data fetching and rendering can happen in parallel, and the data is often already available when the component renders.

  • Reduced Client-Side Hydration: Because RSCs produce a lightweight "RSC Payload" rather than requiring client-side JavaScript to render their content from scratch, the client has less work to do to "hydrate" the UI, leading to faster interactivity.

  • Server-Side Logic & Security: RSCs can run sensitive server-side logic and directly access resources that should never be exposed to the client (e.g., database credentials, API keys). This enhances security and simplifies the overall architecture for asynchronous data loading.

  • Automatic Code Splitting: Since only Client Components and their dependencies are shipped to the browser, RSCs inherently provide fine-grained code splitting.

Can a React Server Component directly use state (useState) or lifecycle effects (useEffect)? Why or why not?

No, a React Server Component cannot directly use state (useState) or React Hooks like useEffect, useRef, or useCallback.

Why not?

  • Execution Environment: React Server Components execute and render entirely on the server (or at build time). They are not designed to run in the browser.

  • No Client-Side Lifecycle: Since they don't run in the browser, there's no client-side component lifecycle for useEffect to tap into (like mounting, updating, unmounting) and no persistent client-side memory for useState to manage.

  • Statelessness (Client-Side Interactive State): RSCs are conceptually "stateless" in terms of interactive client-side UI state. Their purpose is to produce the initial UI rapidly and potentially stream updates. Any interactivity or client-side state management must be handled by Client Components, which are explicitly marked with "use client".

RSCs can fetch data and generate UI based on that data, acting as a "pure function" of their props and server-side data, but they don't maintain interactive state themselves.

Final thoughts

This interview guide covers most of the key React concepts at beginner, intermediate, and advanced levels. Review the fundamentals, go through the examples in this guide, and most importantly, start working on React project ideas to gain experience and share your solutions to get feedback from the community.

As always, practice makes perfect. Practicing with the flashcards or working hand in hand with our AI Tutor will help you stand out from other candidates. 

And don’t forget, it’s not just your coding skills they want to test, but your overall knowledge of the concepts, confidence, and soft skills like communication and teamwork. So present yourself as a well-rounded candidate who is ready to crush it. 

If you want a structured path to strengthen your skills further, check out the React roadmap for a step-by-step guide to mastering the language.

Join the Community

search.highfps.fun is the 6th most starred project on GitHub and is visited by hundreds of thousands of developers every month.

Rank 6th out of 28M!

350K

GitHub Stars

Star us on GitHub
Help us reach #1

+90kevery month

+2.8M

Registered Users

Register yourself
Commit to your growth

+2kevery month

45K

Discord Members

Join on Discord
Join the community

RoadmapsGuidesFAQsYouTube

search.highfps.funby@kamrify

Community created roadmaps, best practices, projects, articles, resources and journeys to help you choose your path and grow in your career.

© search.highfps.fun·Terms·Privacy·

ThewNewStack

The top DevOps resource for Kubernetes, cloud-native computing, and large-scale development and deployment.