20 min read

Interview Prep: 50 React.js Questions And Answers - A Deep Dive for Juniors

Interview Questions: React.js

Getting a job in React.js requires a deep understanding of its core concepts, features, and best practices. This guide helps you prepare for interviews by covering essential questions with detailed answers and examples.

1. What is React.js?

Answer: React.js is an open-source JavaScript library developed by Facebook for building user interfaces or UI components. It focuses on building reusable UI components and managing the state of these components efficiently.

2. What are the key features of React.js?

Answer: React.js has several key features:

  • Virtual DOM: A lightweight copy of the actual DOM that React updates and diffing to compute the minimal necessary updates to the actual DOM.
  • JSX: A syntax extension for JavaScript that allows you to write HTML-like code within your JavaScript code.
  • Reusable Components: Building blocks that encapsulate behavior and can be reused across the application.
  • Unidirectional Data Flow: Data flows in one direction, making it easier to debug and reason about the app’s state.

3. What is JSX?

Answer: JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write HTML-like code within your JavaScript code. JSX tags are transpiled into JavaScript objects that React uses to construct the DOM.

Example:

const element = <h1>Hello, React!</h1>;

4. What is the difference between Element and Component in React?

Answer:

  • Element: A plain object describing a component instance or a DOM node. It specifies the type of the component and its properties. Elements are immutable and describe the UI at a certain point in time.
  • Component: A function or class that optionally accepts input (props) and returns a React element. Components can be functional or class-based.

Example:

const element = <Element Component />;

5. What are props in React?

Answer: Props (short for properties) are inputs to a React component that allow you to pass data from parent to child components. They are read-only and immutable.

Example:

function ChildComponent(props) {
  return <div>{props.message}</div>;
}

function ParentComponent() {
  return <ChildComponent message="Hello from Parent!" />;
}

6. What is state in React?

Answer: State is a data structure that holds a component’s dynamic data and determines the component’s behavior. State is mutable and can be changed using the setState method.

Example:

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>
    );
  }
}

7. What is the difference between state and props?

Answer:

  • State: Managed within the component and can be changed over time. It is used to control the component’s behavior and render output.
  • Props: Immutable and passed down from parent to child components. They are read-only and cannot be changed directly by the child component.

8. What is a controlled component in React?

Answer: A controlled component is a component whose value is controlled by React and not by the DOM. The component’s state is the only source of truth, and the input form element’s value is bound to that state.

Example:

class InputComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { inputValue: "" };
  }

  handleChange = (event) => {
    this.setState({ inputValue: event.target.value });
  };

  render() {
    return (
      <input
        type="text"
        value={this.state.inputValue}
        onChange={this.handleChange}
      />
    );
  }
}

9. What is the purpose of the key attribute in React lists?

Answer: The key attribute is used by React to identify which items have changed, are added, or are removed from a list, improving performance and preventing unexpected behavior. Keys should be unique among siblings.

Example:

const items = ["Apple", "Banana", "Cherry"];
const listItems = items.map((item) => <li key={item}>{item}</li>);

10. What is the context in React?

Answer: Context provides a way to pass data through the component tree without having to pass props down manually at every level. It is useful for global data like theme settings or user authentication.

Example:

const ThemeContext = React.createContext("light");

function ThemedButton() {
  return (
    <ThemeContext.Consumer>
      {(theme) => <button style={{ background: theme }}>Button</button>}
    </ThemeContext.Consumer>
  );
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

11. What is the significance of refs in React?

Answer: Refs are used to reference DOM elements or class component instances in React. They are useful for accessing the DOM directly, measuring nodes, or triggering imperative animations.

Example:

class InputComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  focusInput = () => {
    this.inputRef.current.focus();
  };

  render() {
    return (
      <div>
        <input ref={this.inputRef} />
        <button onClick={this.focusInput}>Focus Input</button>
      </div>
    );
  }
}

12. What are higher-order components (HOCs) in React?

Answer: Higher-order components are functions that take a component and return a new component with enhanced functionality. HOCs are a common pattern for reusing component logic.

Example:

function withUsername(WrappedComponent) {
  return class extends React.Component {
    state = { username: "JohnDoe" };

    render() {
      return <WrappedComponent username={this.state.username} />;
    }
  };
}

function Profile(props) {
  return <h1>Username: {props.username}</h1>;
}

const ProfileWithUsername = withUsername(Profile);

13. What is Redux?

Answer: Redux is a predictable state container for JavaScript applications used to manage the application’s state in a predictable way. It helps in maintaining a global state and handling complex state logic.

14. What are the key principles of Redux?

Answer:

  • Single Source of Truth: The entire state of the app is stored in a single store, making it easier to manage and debug.
  • State is Read-Only: The only way to change the state is to emit an action, an object describing what happened.
  • Changes are Made with Pure Functions: To specify how the state tree is transformed by actions, you write pure reducers.

15. What is the difference between React.js and React Native?

Answer:

  • React.js: A JavaScript library for building user interfaces for web applications.
  • React Native: A framework for building cross-platform mobile applications using React.

16. What are hooks in React?

Answer: Hooks are functions that let you use state and other React features in functional components instead of writing class components. They provide a way to extract stateful logic from components so it can be tested and reused independently.

17. What are the basic hooks provided by React?

Answer:

  • useState: Manages component state.
  • useEffect: Performs side effects in functional components.
  • useContext: Consumes a context value.
  • useReducer: Manages complex state logic.
  • useMemo: Memoizes values to prevent expensive calculations on every render.
  • useCallback: Memoizes functions to prevent unnecessary re-renders of child components.

18. What is the useEffect hook used for?

Answer: The useEffect hook is used to perform side effects in functional components, such as data fetching, subscriptions, or manually changing the DOM.

Example:

import React, { useEffect } from "react";

function DataFetchingComponent() {
  useEffect(() => {
    const fetchData = async () => {
      const response = await fetch("https://api.example.com/data");
      const data = await response.json();
      console.log(data);
    };

    fetchData();

    return () => {
      // Cleanup code
    };
  }, []);

  return <div>Data Fetching Component</div>;
}

19. How do you optimize performance in React?

Answer:

  • Memoization: Use React.memo for functional components and PureComponent for class components to prevent unnecessary re-renders.
  • Avoid Unnecessary Re-renders: Use shouldComponentUpdate or React.memo to avoid re-renders if props or state haven’t changed.
  • Use Virtualized Lists: Render only the visible items in large lists using libraries like react-window or react-virtualized.

20. What is server-side rendering in React?

Answer: Server-side rendering (SSR) is the process of rendering React components on the server side and sending the final HTML to the client, improving performance and SEO. Libraries like Next.js and Gatsby support SSR.

21. What is the purpose of the React Router library?

Answer: React Router is a library that provides routing capabilities to a React application, allowing you to define multiple routes and navigate between them. It helps in building single-page applications (SPAs).

Example:

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Home from "./Home";
import About from "./About";

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

22. How do you handle forms in React?

Answer: You can handle forms in React by using controlled components, which keep the form data in the component’s state and update it based on user input.

Example:

class FormComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { inputValue: "" };
  }

  handleChange = (event) => {
    this.setState({ inputValue: event.target.value });
  };

  handleSubmit = (event) => {
    event.preventDefault();
    console.log(this.state.inputValue);
  };

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type="text"
          value={this.state.inputValue}
          onChange={this.handleChange}
        />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

23. What is the React.Fragment component used for?

Answer: React.Fragment is used to group multiple elements in a single parent element without adding extra nodes to the DOM.

Example:

function MyComponent() {
  return (
    <React.Fragment>
      <h1>Title</h1>
      <p>Description</p>
    </React.Fragment>
  );
}

24. What are portals in React?

Answer: Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component, allowing you to render content in a different part of the DOM tree.

Example:

const ModalComponent = ({ children }) =>
  ReactDOM.createPortal(
    <div className="modal">{children}</div>,
    document.getElementById("modal-root")
  );

25. How do you handle events in React?

Answer: You can handle events in React by using camelCase event names, passing event handlers as props, and calling preventDefault or stopPropagation as needed.

Example:

class ButtonComponent extends React.Component {
  handleClick = (event) => {
    event.preventDefault();
    console.log("Button clicked");
  };

  render() {
    return <button onClick={this.handleClick}>Click Me</button>;
  }
}

26. What is the purpose of the componentDidCatch method in React?

Answer: The componentDidCatch method is used to catch JavaScript errors in a component tree and log those errors, displaying a fallback UI instead of crashing the whole application.

Example:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, errorInfo) {
    this.setState({ hasError: true });
    console.error(error, errorInfo);
  }

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

27. How do you conditionally render components in React?

Answer: You can conditionally render components in React by using JavaScript expressions within JSX or by using conditional rendering with if statements or ternary operators.

Example:

function Greeting(props) {
  if (props.isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign up.</h1>;
}

28. What is the purpose of the shouldComponentUpdate method?

Answer: The shouldComponentUpdate method is used to let React know if a component’s output is affected by a change in props or state, allowing you to prevent unnecessary re-renders.

Example:

class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return nextProps.value !== this.props.value;
  }

  render() {
    return <div>{this.props.value}</div>;
  }
}

29. What are keys in React and why are they important?

Answer: Keys are special string attributes used by React to identify which items have changed, are added, or are removed in a list, helping React optimize rendering performance.

Example:

const items = ["Apple", "Banana", "Cherry"];
const listItems = items.map((item, index) => <li key={index}>{item}</li>);

30. How do you update the state of a component in React?

Answer: You can update the state of a component in React by calling the setState method and passing it an object with the new state values.

Example:

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>
    );
  }
}

31. What is the purpose of the getDerivedStateFromProps method?

Answer: The getDerivedStateFromProps method is a static method used to update the state of a component based on changes in props, returning an object to update the state or null to indicate no changes are needed.

Example:

class MyComponent extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

  constructor(props) {
    super(props);
    this.state = { color: props.color };
  }

  render() {
    return <div style={{ color: this.state.color }}>Colored div</div>;
  }
}

32. What are the different lifecycle methods in React?

Answer: The different lifecycle methods in React include:

  • Mounting Methods:
    • constructor
    • render
    • componentDidMount
  • Updating Methods:
    • render
    • getDerivedStateFromProps
    • shouldComponentUpdate
    • componentDidUpdate
  • Unmounting Methods:
    • componentWillUnmount

33. What is the purpose of the React.memo function?

Answer: The React.memo function is a higher-order component that memoizes a functional component, preventing unnecessary re-renders if the component’s props have not changed.

Example:

const MyComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

34. How do you handle errors in React?

Answer: You can handle errors in React by using error boundaries, which are special components that catch JavaScript errors in their child component tree and display a fallback UI instead of crashing the whole application.

Example:

const ErrorBoundary = ({ children }) => {
  const [hasError, setHasError] = React.useState(false);

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

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

  if (hasError) {
    return <h1>Something went wrong.</h1>;
  }

  return children;
};

35. What is the purpose of the PureComponent class in React?

Answer: The PureComponent class is a class component that implements shouldComponentUpdate with a shallow prop and state comparison, preventing unnecessary re-renders if the component’s props and state have not changed.

Example:

class MyComponent extends React.PureComponent {
  render() {
    return <div>{this.props.value}</div>;
  }
}

36. What is the purpose of the dangerouslySetInnerHTML attribute in React?

Answer: The dangerouslySetInnerHTML attribute is used to set HTML directly from React, bypassing React’s XSS protection. It should be used with caution as it can make your application vulnerable to XSS attacks.

Example:

const dangerousHtml = { __html: "<div>Content</div>" };

function MyComponent() {
  return <div dangerouslySetInnerHTML={dangerousHtml} />;
}

37. What is the difference between createElement and cloneElement in React?

Answer:

  • createElement: Used to create a new React element. It takes three main arguments: the type of the element (a string for DOM tags or a reference to a component), props for the element, and children elements.
  • cloneElement: Used to clone an existing element and pass new props to it. This is useful for modifying or extending the props of an existing element.

Example:

import React from "react";

// Using createElement
const element = React.createElement(
  "h1",
  { className: "greeting" },
  "Hello, React!"
);

// Using cloneElement
const clonedElement = React.cloneElement(element, { style: { color: "blue" } });

function App() {
  return (
    <div>
      {element}
      {clonedElement}
    </div>
  );
}

38. What is the purpose of the componentDidUpdate method in React?

Answer: The componentDidUpdate method is called after a component’s updates are flushed to the DOM. It allows you to perform side effects after the component has been updated, such as making network requests based on new props.

Example:

class MyComponent extends React.Component {
  componentDidUpdate(prevProps) {
    if (this.props.userID !== prevProps.userID) {
      this.fetchData(this.props.userID);
    }
  }

  fetchData(userID) {
    console.log(`Fetching data for user ${userID}`);
  }

  render() {
    return <div>User ID: {this.props.userID}</div>;
  }
}

39. What are forward refs in React?

Answer: Forward refs allow you to pass refs through a component to its child components. This is useful when you need to access the DOM node or React element of a child component from a parent component.

Example:

import React from "react";

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

function App() {
  const ref = React.createRef();

  return (
    <div>
      <FancyButton ref={ref}>Click me!</FancyButton>
      <button onClick={() => alert(ref.current.textContent)}>
        Log Button Text
      </button>
    </div>
  );
}

40. What is the purpose of the static getDerivedStateFromError method?

Answer: The static getDerivedStateFromError method is used to update the state of a component when an error is thrown in a descendant component. It allows the component to render a fallback UI instead of crashing.

Example:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

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

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

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

    return this.props.children;
  }
}

41. What is the purpose of the createRef method in React?

Answer: The createRef method is used to create a ref that can be attached to a React element or a DOM node. It allows you to access the element or node imperatively.

Example:

import React from "react";

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  focusInput = () => {
    this.inputRef.current.focus();
  };

  render() {
    return (
      <div>
        <input ref={this.inputRef} />
        <button onClick={this.focusInput}>Focus Input</button>
      </div>
    );
  }
}

42. What is the purpose of the useContext hook in React?

Answer: The useContext hook is used to consume a React context in a functional component. It allows you to access the context value without having to use a class component or a consumer component.

Example:

import React, { useContext, createContext } from "react";

const ThemeContext = createContext("light");

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return <button style={{ background: theme }}>Button</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

43. What is the difference between useMemo and useCallback hooks in React?

Answer:

  • useMemo: Memoizes a value to prevent expensive calculations on every render. It caches the result and returns the cached value if the dependencies haven’t changed.
  • useCallback: Memoizes a function to prevent unnecessary re-renders of child components. It caches the function and returns the cached function if the dependencies haven’t changed.

Example:

import React, { useMemo, useCallback, useState } from "react";

function App() {
  const [count, setCount] = useState(0);
  const [inputValue, setInputValue] = useState("");

  const expensiveValue = useMemo(() => {
    console.log("Calculating...");
    return count * 2;
  }, [count]);

  const handleChange = useCallback((event) => {
    setInputValue(event.target.value);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <p>Expensive Value: {expensiveValue}</p>
      <input value={inputValue} onChange={handleChange} />
    </div>
  );
}

44. What is the purpose of the useReducer hook in React?

Answer: The useReducer hook is used to manage complex state logic in a component by using a reducer function, similar to how Redux manages state in an application. It is particularly useful when you have state logic that involves multiple sub-values or when the next state depends on the previous one.

Example:

import React, { useReducer } from "react";

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: "increment" })}>+</button>
      <button onClick={() => dispatch({ type: "decrement" })}>-</button>
    </div>
  );
}

45. How do you test React components?

Answer: You can test React components using libraries like Jest and React Testing Library, which provide utilities for rendering components, interacting with them, and asserting their behavior.

Example:

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import "@testing-library/jest-dom/extend-expect";
import Counter from "./Counter";

test("increments count", () => {
  render(<Counter />);
  const countText = screen.getByText(/count:/i);
  const incrementButton = screen.getByText(/\+/i);

  fireEvent.click(incrementButton);

  expect(countText).toHaveTextContent(/count: 1/i);
});

46. What is the purpose of the React.StrictMode component?

Answer: The React.StrictMode component is used to highlight potential problems in a React application during development, such as deprecated lifecycle methods and unsafe lifecycle methods. It helps in identifying and fixing them early in the development process.

Example:

import React from "react";

function App() {
  return (
    <React.StrictMode>
      <div>
        <p>Hello, React!</p>
      </div>
    </React.StrictMode>
  );
}

47. How do you integrate third-party libraries with React?

Answer: You can integrate third-party libraries with React by either using them directly in your components or by creating custom React components that wrap the functionality of the third-party library.

Example: Integrating a third-party charting library like Chart.js:

import React, { useRef, useEffect } from "react";
import Chart from "chart.js/auto";

function ChartComponent() {
  const chartRef = useRef(null);

  useEffect(() => {
    const ctx = chartRef.current.getContext("2d");
    new Chart(ctx, {
      type: "bar",
      data: {
        labels: ["January", "February", "March"],
        datasets: [
          {
            label: "Monthly Sales",
            data: [50, 60, 70],
            backgroundColor: "rgba(54, 162, 235, 0.2)",
            borderColor: "rgba(54, 162, 235, 1)",
            borderWidth: 1,
          },
        ],
      },
      options: {
        scales: {
          y: {
            beginAtZero: true,
          },
        },
      },
    });
  }, []);

  return <canvas ref={chartRef} />;
}

export default ChartComponent;

48. What is the purpose of the useLayoutEffect hook in React?

Answer: The useLayoutEffect hook is similar to useEffect but fires synchronously after all DOM mutations, allowing you to perform actions that require the DOM to be updated before continuing.

Example: Measuring the size of a DOM element after it has been rendered:

import React, { useLayoutEffect, useRef } from "react";

function MeasurementComponent() {
  const divRef = useRef(null);

  useLayoutEffect(() => {
    if (divRef.current) {
      console.log("Width:", divRef.current.offsetWidth);
      console.log("Height:", divRef.current.offsetHeight);
    }
  }, []);

  return <div ref={divRef}>Measure Me</div>;
}

export default MeasurementComponent;

49. How do you handle authentication in a React application?

Answer: You can handle authentication in a React application by using libraries like Auth0 or Firebase, storing tokens in local storage or cookies, and protecting routes based on the authentication status.

Example: Using Firebase for authentication:

import React, { useState, useEffect } from "react";
import firebase from "firebase/app";
import "firebase/auth";
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";

// Initialize Firebase
firebase.initializeApp({
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
});

function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
      setUser(user);
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  if (loading) {
    return <div>Loading...</div>;
  }

  return (
    <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>
  );
}

const ProtectedRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      rest.authContext.user ? (
        <Component {...props} />
      ) : (
        <Redirect to="/login" />
      )
    }
  />
);

function App() {
  return (
    <AuthProvider>
      <BrowserRouter>
        <Switch>
          <ProtectedRoute path="/dashboard" component={Dashboard} />
          <Route path="/login" component={Login} />
        </Switch>
      </BrowserRouter>
    </AuthProvider>
  );
}

50. What are some best practices for writing React components?

Answer:

  • Keep Components Small and Focused: Break down large components into smaller, reusable components.
  • Use Functional Components When Possible: Functional components are simpler and easier to test.
  • Use Hooks for Stateful Logic: Use hooks like useState, useEffect, and useContext for managing state and side effects in functional components.
  • Follow Naming Conventions for Props and State Variables: Use clear and descriptive names for props and state variables to improve readability and maintainability.
  • Use Proper Error Handling: Use error boundaries to handle errors gracefully.
  • Optimize Component Performance: Use React.memo, useMemo, and useCallback to optimize performance by preventing unnecessary re-renders.

By mastering these concepts and practices, you’ll be well-prepared for React.js interviews and able to write efficient, maintainable, and user-friendly React applications.