React Interview Questions

  1. 1. What are the main features of React?

    • Answer:

      • Component-Based Architecture: Breaks UI into reusable, self-contained components.

      • Virtual DOM: Minimizes DOM manipulation by updating only the changed parts.

      • Unidirectional Data Flow: Data flows in one direction, simplifying state management.

      • JSX (JavaScript XML): A syntax extension that allows HTML within JavaScript.

      • Declarative: Describes what the UI should look like, making it easier to read and manage.


2. What is the difference between State and Props?

  • Answer:

    • State:

      • Managed within a component.

      • Mutable (can change over time).

      • Controls component behavior and rendering.

    • Props:

      • Passed from a parent to a child component.

      • Immutable (cannot be changed by the receiving component).

      • Used to pass data and trigger callbacks.


3. What is the Virtual DOM, and how does it improve performance?

  • Answer:

    • Virtual DOM is an in-memory representation of the actual DOM. React maintains it as a lightweight copy.

    • When state or props change, React updates the Virtual DOM first, compares it with the real DOM, and then only applies the differences.

    • This minimizes costly direct manipulations of the real DOM, improving performance.


4. Explain the React Component Lifecycle?

  • Answer:

    • The component lifecycle is divided into three phases:

      1. Mounting: constructor(), static getDerivedStateFromProps(), render(), componentDidMount().

      2. Updating: static getDerivedStateFromProps(), shouldComponentUpdate(), render(), getSnapshotBeforeUpdate(), componentDidUpdate().

      3. Unmounting: componentWillUnmount().

    • Hooks can also be used in functional components to mimic lifecycle methods (e.g., useEffect() for componentDidMount).

      Summary of Mimicking Lifecycle Phases with Hooks

      | Lifecycle Phase | Class Component Method(s) | Functional Component (Hooks) | | --- | --- | --- | | Mounting | constructor, componentDidMount | useEffect(() => {}, []) | | Updating | shouldComponentUpdate, componentDidUpdate, getDerivedStateFromProps, getSnapshotBeforeUpdate | useEffect(() => {}, [dependencies]), React.memo, useCallback | | Unmounting | componentWillUnmount | useEffect(() => { return () => {}; }, []) |


5. What is the difference between Functional and Class Components?

  • Answer:

    • Functional Components: Use functions, introduced with React 16.8 with hooks (useState, useEffect, etc.), making them lightweight and easy to test.

    • Class Components: Use ES6 classes, more complex with lifecycle methods, this keyword, and state. They are generally less favored for new projects.


6. How does React’s useEffect hook work?

  • Answer:

    • useEffect allows you to perform side effects (e.g., data fetching, subscriptions) in functional components.

    • Syntax: useEffect(() => { /* effect */ }, [dependencies]);

    • Dependencies Array:

      • Controls when the effect re-runs.

      • Leaving it empty ([]) runs the effect only on mount/unmount.

      • Including variables triggers re-runs when they change.


7. What is Context API, and when should you use it?

  • Answer:

    • Context API enables sharing state across components without prop drilling.

    • Best Use Cases:

      • When data needs to be accessible by many nested components (e.g., theme, authentication state).
    • Usage: Wrap components in a Context.Provider, access data using useContext.

        import React, { createContext, useState } from 'react';
      
        // Create the Context
        export const ThemeContext = createContext();
      
        // Create a Provider component
        export const ThemeProvider = ({ children }) => {
           const [theme, setTheme] = useState("light"); // 'light' or 'dark'
      
           // Function to toggle theme
           const toggleTheme = () => {
              setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
           };
      
           return (
              <ThemeContext.Provider value={{ theme, toggleTheme }}>
                 {children}
              </ThemeContext.Provider>
           );
        };
      

8. What is Redux, and how does it work with React?

  • Answer:

    • Redux is a state management library that manages the application state globally.

    • Core Concepts:

      • Store: Holds the entire application state.

      • Actions: Plain objects that describe the change.

      • Reducers: Pure functions that return a new state based on actions.

    • React components access the state via useSelector and dispatch actions via useDispatch.

  •   import React from 'react';
      import ReactDOM from 'react-dom/client';
      import { configureStore, createSlice } from '@reduxjs/toolkit';
      import { Provider, useDispatch, useSelector } from 'react-redux';
    
      // Step 1: Create a theme slice with initial state, reducers, and actions
      const themeSlice = createSlice({
         name: 'theme',
         initialState: { mode: 'light' }, // initial theme state is 'light'
         reducers: {
            toggleTheme: (state) => {
               // Toggles theme between 'light' and 'dark'
               state.mode = state.mode === 'light' ? 'dark' : 'light';
            }
         }
      });
    
      // Export the action for use in components
      const { toggleTheme } = themeSlice.actions;
    
      // Step 2: Create a Redux store and add themeSlice to it
      const store = configureStore({
         reducer: {
            theme: themeSlice.reducer
         }
      });
    
      // Step 3: Create a component that consumes the theme state and dispatches actions
      const HomePage = () => {
         const dispatch = useDispatch(); // Access the dispatch function
         const theme = useSelector((state) => state.theme.mode); // Access the theme mode from the Redux store
    
         return (
            <div
               style={{
                  background: theme === 'light' ? '#fff' : '#333',
                  color: theme === 'light' ? '#000' : '#fff',
                  padding: '20px',
                  textAlign: 'center'
               }}
            >
               <h1>{theme === 'light' ? 'Light Mode' : 'Dark Mode'}</h1>
               {/* Dispatch the toggleTheme action on button click */}
               <button onClick={() => dispatch(toggleTheme())}>Toggle Theme</button>
            </div>
         );
      };
    
      // Step 4: Wrap the app in the Redux Provider to provide the Redux store to all components
      const App = () => {
         return (
            <Provider store={store}>
               <HomePage />
            </Provider>
         );
      };
    
      // Render the app
      const root = ReactDOM.createRoot(document.getElementById('root'));
      root.render(<App />);
    

9. What are React Hooks, and why were they introduced?

  • Answer:

    • Hooks allow functional components to have state and other features that were previously only available in class components.

    • Common Hooks:

      • useState for state.

      • useEffect for side effects.

      • useContext for context.

    • Benefits: Simplifies code, reduces boilerplate, encourages more functional programming.


10. What is lazy loading, and how do you implement it in React?

  • Answer:

    • Lazy Loading is a technique to load components or resources only when they are needed.

    • In React, use React.lazy along with Suspense to split your code.

    • Example:

        const LazyComponent = React.lazy(() => import('./LazyComponent'));
        // Usage
        <Suspense fallback={<div>Loading...</div>}>
           <LazyComponent />
        </Suspense>
      

11. How do you optimize the performance of a React application?

  • Answer:

    • Use React.memo and useMemo to avoid unnecessary re-renders.

    • Implement code-splitting using React.lazy and dynamic imports.

    • Use shouldComponentUpdate or React.PureComponent for class components.

    • Avoid anonymous functions in render and pass stable callbacks using useCallback.

    • Optimize dependency arrays in useEffect and other hooks.


12. What is Prop Drilling, and how do you avoid it?

  • Answer:

    • Prop Drilling occurs when props are passed down multiple levels to reach a specific component.

    • Avoidance Techniques:

      • Use Context API or Redux for global state management.

      • Utilize custom hooks to encapsulate logic and share state.


13. What is the purpose of key in React, and why should they be unique?

  • Answer:

    • The key prop helps React identify which items have changed, been added, or removed.

    • It should be unique among siblings to optimize re-rendering. Without unique keys, React may render incorrectly.


14. Explain controlled vs. uncontrolled components in React.

  • Answer:

    • Controlled Components: Have their state managed by React; updates occur via onChange handlers.

    • Uncontrolled Components: Rely on the DOM to handle state; use ref to access values.


15. How does error handling work in React?

  • Answer:

    • Use Error Boundaries (class components with componentDidCatch) to catch errors in child components.

    • In functional components, libraries like ErrorBoundary or using custom ErrorBoundary components can help handle errors gracefully.


These answers will help you demonstrate not only your React skills but also your problem-solving approach and understanding of best practices during your interview. Let me know if you want more advanced questions or specific scenarios!

Differences between React.memo and useMemo

FeatureReact.memouseMemo
Type of OptimizationMemoizes the entire component (prevents re-renders)Memoizes values or the result of a computation
Use caseUse when you want to prevent unnecessary re-renders of a componentUse when you want to prevent expensive calculations from running on every render
Works OnFunctional componentsValues or functions (calculations, objects, etc.)
How It WorksIt compares props to determine if the component needs to re-renderIt memoizes the return value of a function based on dependencies
Shallow ComparisonYes, compares props shallowlyNo, it does not perform any comparison, it only recalculates when dependencies change
SyntaxReact.memo(Component)useMemo(() => expensiveFunction(), [dependency])

16. Define a Callback Function in the Parent Component

1. Define a Callback Function in the Parent Component

  • The parent component creates a function that will handle data received from the child component. This function will be passed as a prop to the child.

2. Pass the Callback Function as a Prop to the Child Component

  • When you render the child component in the parent, pass the callback function as a prop to the child.

3. Invoke the Callback Function in the Child Component

  • Inside the child component, call the function passed via props and pass any data you want to send to the parent as an argument.

Example

Let’s go through an example where a child component sends an input value to its parent:

Parent Component (ParentComponent.js)

    import React, { useState } from 'react';
    import ChildComponent from './ChildComponent';

    function ParentComponent() {
       const [childData, setChildData] = useState("");

       // Step 1: Define a callback function in the parent
       const handleDataFromChild = (data) => {
          setChildData(data); // Update the state with data from the child
       };

       return (
          <div>
             <h1>Data from Child: {childData}</h1>
             {/* Step 2: Pass the callback function to the child */}
             <ChildComponent onData={handleDataFromChild} />
          </div>
       );
    }

    export default ParentComponent;

Child Component (ChildComponent.js)

    import React, { useState } from 'react';

    function ChildComponent({ onData }) {
       const [inputValue, setInputValue] = useState("");

       const handleChange = (event) => {
          setInputValue(event.target.value);
       };

       // Step 3: Call the parent’s callback function when needed
       const sendDataToParent = () => {
          onData(inputValue); // Pass data to parent
       };

       return (
          <div>
             <input
                type="text"
                value={inputValue}
                onChange={handleChange}
                placeholder="Type something..."
             />
             <button onClick={sendDataToParent}>Send to Parent</button>
          </div>
       );
    }

    export default ChildComponent;

Explanation

  • handleDataFromChild in ParentComponent receives the data from ChildComponent.

  • onData={handleDataFromChild}: Passes the function to ChildComponent via the onData prop.

  • onData(inputValue): The child component calls this function when the button is clicked, sending inputValue up to the parent.

Result

This method allows the parent component to receive and store data from the child component in its state.