Interview

15 React Frontend Interview Questions and Answers

Prepare for your next technical interview with our comprehensive guide on React Frontend, featuring common and advanced questions and answers.

React has become a cornerstone in modern web development, known for its efficiency in building dynamic and responsive user interfaces. Its component-based architecture allows developers to create reusable UI components, making code more maintainable and scalable. React’s popularity is further bolstered by a strong community and a rich ecosystem of tools and libraries that enhance its capabilities.

This article offers a curated selection of interview questions designed to test your understanding and proficiency in React. By working through these questions and their detailed answers, you’ll be better prepared to demonstrate your expertise and problem-solving skills in any technical interview setting.

React Frontend Interview Questions and Answers

1. How would you use the useState and useEffect hooks in a functional component?

In React, the useState and useEffect hooks are used for managing state and side effects in functional components. useState adds state to a component, while useEffect handles side effects like data fetching or event subscriptions.

Example:

import React, { useState, useEffect } from 'react';

function ExampleComponent() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        document.title = `You clicked ${count} times`;
    }, [count]);

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}

In this example, useState creates a state variable count and a function setCount to update it. useEffect updates the document title whenever count changes.

2. Create a controlled form component that handles user input.

A controlled component in React is a form element whose value is controlled by the component’s state. This allows for predictable and consistent form data management.

Example:

import React, { useState } from 'react';

function ControlledForm() {
    const [inputValue, setInputValue] = useState('');

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

    const handleSubmit = (event) => {
        event.preventDefault();
        alert('Submitted value: ' + inputValue);
    };

    return (
        <form onSubmit={handleSubmit}>
            <label>
                Input:
                <input type="text" value={inputValue} onChange={handleChange} />
            </label>
            <button type="submit">Submit</button>
        </form>
    );
}

export default ControlledForm;

In this example, useState manages the input value, and handleChange updates the state when the input changes.

3. What is the Context API and when would you use it?

The Context API in React allows data to be passed through the component tree without manually passing props at every level. It’s useful for global state management, such as user authentication or theme settings.

Example:

import React, { createContext, useState, useContext } from 'react';

const ThemeContext = createContext();

const ThemeProvider = ({ children }) => {
    const [theme, setTheme] = useState('light');

    return (
        <ThemeContext.Provider value={{ theme, setTheme }}>
            {children}
        </ThemeContext.Provider>
    );
};

const useTheme = () => useContext(ThemeContext);

const ThemedComponent = () => {
    const { theme, setTheme } = useTheme();

    return (
        <div>
            <p>Current theme: {theme}</p>
            <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
                Toggle Theme
            </button>
        </div>
    );
};

const App = () => (
    <ThemeProvider>
        <ThemedComponent />
    </ThemeProvider>
);

export default App;

4. What strategies can you use to optimize the performance of a React application?

To optimize React application performance, consider strategies like code-splitting, lazy loading, memoization, and using the React Profiler. Proper state management and virtualization for large lists can also enhance performance.

5. How do you manage complex state in a React application using Redux or another state management library?

Managing complex state in React can be handled using libraries like Redux, which provides a structured way to manage application state. Redux uses actions, reducers, and a store to manage state changes.

Example:

// actions.js
export const increment = () => ({
  type: 'INCREMENT'
});

export const decrement = () => ({
  type: 'DECREMENT'
});

// reducer.js
const initialState = { count: 0 };

const counter = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

export default counter;

// store.js
import { createStore } from 'redux';
import counter from './reducer';

const store = createStore(counter);

export default store;

// App.js
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
import store from './store';
import { increment, decrement } from './actions';

const Counter = () => {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch(decrement())}>-</button>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>+</button>
    </div>
  );
};

const App = () => (
  <Provider store={store}>
    <Counter />
  </Provider>
);

export default App;

6. Write a custom hook to fetch data from an API.

Custom hooks in React allow you to extract and reuse logic across components. They are functions that start with “use” and can call other hooks.

Example of a custom hook to fetch data:

import { useState, useEffect } from 'react';

const useFetch = (url) => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await fetch(url);
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                const result = await response.json();
                setData(result);
            } catch (error) {
                setError(error);
            } finally {
                setLoading(false);
            }
        };

        fetchData();
    }, [url]);

    return { data, loading, error };
};

export default useFetch;

7. What is code splitting and how does it benefit a React application?

Code splitting in React can be achieved using dynamic imports and React.lazy. By splitting the code into smaller chunks, the application can load only the necessary code for the current user interaction, rather than loading the entire application at once.

Example:

import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <LazyComponent />
      </Suspense>
    </div>
  );
}

export default App;

In this example, the LazyComponent is loaded only when it is needed, rather than being included in the initial bundle.

8. Explain server-side rendering and its benefits in a React application.

Server-side rendering (SSR) in a React application means that the React components are rendered on the server, and the fully rendered HTML is sent to the client. This approach can improve performance and user experience.

Benefits of SSR include:

– Improved Performance: The server sends a fully rendered HTML page, leading to faster initial page loads.
– Better SEO: Search engines can crawl and index the fully rendered HTML content more effectively.
– Enhanced User Experience: Users can see the content faster, reducing the time they spend waiting for the page to load.
– Reduced Client-Side Load: Offloading the rendering process to the server can reduce the computational load on the client.

9. How do you ensure type safety in a React application using PropTypes or TypeScript?

Ensuring type safety in a React application can be achieved using either PropTypes or TypeScript. Both methods help catch type-related errors during development.

PropTypes is a runtime type-checking tool that allows you to define the expected types for props in your components.

Example using PropTypes:

import React from 'react';
import PropTypes from 'prop-types';

const MyComponent = ({ name, age }) => (
  <div>
    <p>Name: {name}</p>
    <p>Age: {age}</p>
  </div>
);

MyComponent.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number.isRequired,
};

export default MyComponent;

TypeScript is a statically typed superset of JavaScript that provides compile-time type checking.

Example using TypeScript:

import React from 'react';

interface MyComponentProps {
  name: string;
  age: number;
}

const MyComponent: React.FC<MyComponentProps> = ({ name, age }) => (
  <div>
    <p>Name: {name}</p>
    <p>Age: {age}</p>
  </div>
);

export default MyComponent;

10. What is React Fiber and how does it improve React’s performance?

React Fiber is a reimplementation of the React core algorithm, designed to enhance the performance and responsiveness of React applications. It enables incremental rendering, allowing React to break down rendering work into smaller units and spread it out over multiple frames.

Key improvements introduced by React Fiber include:

– Incremental Rendering: Allows rendering work to be split into smaller chunks, preventing the UI from freezing.
– Prioritization: React Fiber can prioritize updates based on their importance.
– Concurrency: Allows multiple tasks to be processed simultaneously.
– Better Error Handling: Provides improved error handling capabilities.

11. Explain advanced patterns like render props and compound components.

Render Props:
Render props is a pattern where a component’s prop is a function that returns a React element, allowing for greater flexibility and reusability.

Example:

class MouseTracker extends React.Component {
  state = { x: 0, y: 0 };

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    });
  };

  render() {
    return (
      <div style={{ height: '100vh' }} onMouseMove={this.handleMouseMove}>
        {this.props.render(this.state)}
      </div>
    );
  }
}

const App = () => (
  <MouseTracker render={({ x, y }) => (
    <h1>The mouse position is ({x}, {y})</h1>
  )} />
);

Compound Components:
Compound components are a pattern where multiple components work together to form a single, cohesive unit.

Example:

const Tabs = ({ children }) => {
  const [activeIndex, setActiveIndex] = React.useState(0);

  return React.Children.map(children, (child, index) =>
    React.cloneElement(child, {
      isActive: index === activeIndex,
      onSelect: () => setActiveIndex(index)
    })
  );
};

const Tab = ({ isActive, onSelect, children }) => (
  <div onClick={onSelect} style={{ fontWeight: isActive ? 'bold' : 'normal' }}>
    {children}
  </div>
);

const App = () => (
  <Tabs>
    <Tab>Tab 1</Tab>
    <Tab>Tab 2</Tab>
    <Tab>Tab 3</Tab>
  </Tabs>
);

12. What techniques can be used to optimize React application performance?

To optimize the performance of a React application, consider techniques like code splitting, lazy loading, memoization, and virtualization. Efficient state management and event handling can also enhance performance.

13. How do you handle side effects in React applications?

In React, side effects are typically handled using the useEffect hook. It allows you to perform side effects in function components, such as data fetching or setting up subscriptions.

Example:

import React, { useState, useEffect } from 'react';

function DataFetchingComponent() {
    const [data, setData] = useState(null);

    useEffect(() => {
        async function fetchData() {
            const response = await fetch('https://api.example.com/data');
            const result = await response.json();
            setData(result);
        }

        fetchData();
    }, []); // Empty dependency array means this effect runs once after the initial render

    return (
        <div>
            {data ? <pre>{JSON.stringify(data, null, 2)}</pre> : 'Loading...'}
        </div>
    );
}

In this example, useEffect fetches data from an API when the component mounts.

14. What is React Concurrent Mode and how does it improve user experience?

React Concurrent Mode is a set of features that help React apps stay responsive and adjust to the user’s device capabilities and network speed. It allows React to work on multiple tasks at once, pausing and resuming work as needed.

Key features of Concurrent Mode include:

– Time Slicing: Allows React to break rendering work into chunks, ensuring the main thread is not blocked.
– Suspense: Lets you wait for code to load or data to be fetched before rendering a component.
– Interruptible Rendering: React can pause rendering work if something more urgent comes up.

15. Explain the importance of static type checking in React applications and how tools like Flow or TypeScript can be used.

Static type checking is important in React applications because it helps identify type-related errors during development. This leads to more reliable and maintainable code. Tools like Flow and TypeScript are commonly used for static type checking in React applications.

Example using TypeScript in a React component:

import React from 'react';

interface Props {
  name: string;
  age: number;
}

const Greeting: React.FC<Props> = ({ name, age }) => {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>You are {age} years old.</p>
    </div>
  );
};

export default Greeting;

In this example, the Props interface defines the expected types for the name and age props, ensuring type safety.

Previous

10 Control Valve Interview Questions and Answers

Back to Interview