Most Commonly Asked React Interview Questions 2024 - Part 3
Tags: react, webdev, javascript, beginners
Published: 2024-03-15 14:54:03

> If you like this blog, you can visit my personal blog [sehgaltech](https://blog.sehgaltech.com/) for more content.



## 1. How do you handle error boundaries in React?

Error boundaries in React are a way to catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed. Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them.

Here's an example of how you can define an error boundary:

```jsx

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

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

```

You can use it as a regular component:

```jsx

<ErrorBoundary>
  <MyComponent />
</ErrorBoundary>

```

In the above example, if `MyComponent` or any of its children throw an error during rendering, the error will be caught by the `ErrorBoundary`, the fallback UI will be rendered, and the error will be logged.

Please note that error boundaries only catch errors in the components below them in the tree. An error boundary can’t catch an error within itself.

<br>

## 2. What is the use of refs in React?

Refs in React are used to access and interact with DOM nodes or React elements directly. They are used in cases where you need to imperatively modify a child outside of the typical data flow. Here are a few common use cases for refs:

1. Managing focus, text selection, or media playback.
2. Triggering imperative animations.
3. Integrating with third-party DOM libraries.

In functional components, refs are used with the `useRef` hook. Here's an example of how to use refs to manage focus on an input element in a functional component:

```jsx

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

function MyComponent() {
  const myRef = useRef(null);

  useEffect(() => {
    myRef.current.focus();
  }, []);

  return <input ref={myRef} />;
}

```

In this example, `myRef` is a reference to the DOM node rendered by the `<input />` element, so it can be used to access the properties and methods of this node.

It's important to note that you should avoid using refs for anything that can be done declaratively. For example, instead of using a ref to expose text content of a `<span>`, you should pass it as a prop.

<br>

## 3. How do you manage side effects in React?

In React, side effects are managed using a built-in hook called `useEffect`. Side effects are operations that can affect other components and can't be done during rendering. These include data fetching, subscriptions, or manually changing the DOM.

The `useEffect` hook accepts two arguments: a function where you can perform your side effects, and an array of dependencies. The function will run after the render is committed to the screen.

If you pass an empty array (`[]`) as the second argument, the side effect runs once after the initial render, similar to `componentDidMount` in class components. If you pass variables in the array, the side effect will run whenever any of those variables change, similar to `componentDidUpdate`.

Here's an example of using `useEffect` to fetch data from an API:

```jsx

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

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

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []); // Empty array means this effect runs once after initial render

  return (
    <div>
      {data ? `Data: ${data}` : 'Loading...'}
    </div>
  );
}

```

In this example, the `useEffect` hook fetches data from an API and updates the component's state with the fetched data. The empty array (`[]`) means the data fetching happens once after the component mounts.

<br>

## 4. What is the difference between a controlled component and an uncontrolled component?

In React, the terms "controlled" and "uncontrolled" components refer to the way data is managed in form elements. 

1. Controlled Components: Controlled components are components where form data is controlled by React state. Any changes to the input field are handled by functions within the component, which means that the form data is directly controlled by the React component. The value of the input field is always driven by the state in the component. Here's an example:

```jsx

import React, { useState } from 'react';

function MyForm() {
  const [value, setValue] = useState('');

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

  const handleSubmit = (event) => {
    alert('A name was submitted: ' + value);
    event.preventDefault();
  }

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

export default MyForm;

```

2. Uncontrolled Components: Uncontrolled components are components where form data is handled by the DOM itself rather than React state. Instead of writing an event handler for every state update, you can use a `ref` to get form values from the DOM. The value of the input field is thus controlled by the DOM itself, not by the React component. Here's an example:

```jsx

import React from 'react';

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

  handleSubmit = (event) => {
    alert('A name was submitted: ' + this.inputRef.current.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.inputRef} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

export default MyForm;

```

In general, it's recommended to use controlled components because they allow for more predictable code and are more in line with the "React way" of doing things, which is to keep state in the React component's state and render it declaratively. However, uncontrolled components can be useful for some types of inputs, like file uploads, or for integrating with non-React code.

<br>

## 5. How do you test React components?

Testing React components can be done using several libraries and tools. Here are some of the most commonly used ones:

1. **Jest:** Jest is a JavaScript testing framework developed by Facebook. It's great for testing JavaScript and React code. It works out of the box with minimal configuration and has features like a complete and easy-to-use API, mocking support, and a powerful matcher library.

2. **React Testing Library:** This is a very light-weight solution for testing React components. It provides light utility functions on top of `react-dom` and `react-dom/test-utils`, in a way that encourages better testing practices. Its primary guiding principle is: "The more your tests resemble the way your software is used, the more confidence they can give you."

3. **Enzyme:** Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output. Enzyme's API is meant to be intuitive and flexible by mimicking jQuery's API for DOM manipulation and traversal.

Here's an example of how you might test a simple React component using Jest and React Testing Library:

```jsx

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import Button from '../Button'; // This is the component to be tested

test('Check button click updates the count', () => {
  const { getByText } = render(<Button />);

  // Button initially starts with "Times clicked: 0"
  expect(getByText('Times clicked: 0')).toBeInTheDocument();

  // Simulate a button click
  fireEvent.click(getByText('Click me'));

  // Expect the button text to have changed after click
  expect(getByText('Times clicked: 1')).toBeInTheDocument();
});

```

In this example, we're rendering the `Button` component and then checking that the initial button text is as expected. We then simulate a button click and check that the button text updates as expected.

Remember, testing is a vast topic and the approach you take will depend on many factors such as the complexity of the component, whether it's a class or functional component, whether it uses state or props, etc.

<br>

## 6. What is prop drilling in React?

Prop drilling is a term used in the React community to refer to the process of getting data to parts of the React Component tree. This involves passing props down from a parent component to its child components, and then further down to their children, and so on. This can become particularly problematic when the tree depth increases, as components in between that don't need the data still need to be passed the props to provide it to components deeper in the tree.

This is not an issue with small applications or components, but it can become cumbersome in larger applications. It can lead to code that is hard to maintain and understand. To avoid prop drilling, you can use state management solutions like Redux, MobX or React's built-in Context API. These solutions allow you to manage and access state from any component without having to pass props down through intermediate components.

<br>

## 7. What are Custom Hooks?

Custom Hooks are a feature in React that allow you to create your own hooks to reuse stateful behavior between different components. Custom Hooks are JavaScript functions whose names are prefixed with the word 'use'. A custom Hook is a normal function which can use other Hooks inside of it.

The purpose of custom Hooks is to allow you to use component logic into reusable functions. For example, you might want to use the same data fetching logic in multiple components. With custom Hooks, you can extract this logic into a reusable function.

Here's an example of a custom Hook:

```jsx

import { useState, useEffect } from 'react';

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

  useEffect(() => {
    async function fetchData() {
      const response = await fetch(url);
      const data = await response.json();
      setData(data);
      setLoading(false);
    }
    fetchData();
  }, [url]);

  return { data, loading };
}

export default useFetch;

```

In this example, `useFetch` is a custom Hook that fetches data from a URL. It uses the `useState` and `useEffect` Hooks internally. You can use it in your components like this:

```jsx

import React from 'react';
import useFetch from './useFetch';

function MyComponent() {
  const { data, loading } = useFetch('https://api.example.com/data');

  if (loading) {
    return 'Loading...';
  }

  return <div>Data: {data}</div>;
}

```

In this component, we're using the `useFetch` custom Hook to fetch data from an API. The `useFetch` Hook returns an object with `data` and `loading` properties, which we can use in our component to render different content based on whether the data is still loading.

<br>

## 8. Explain Strict Mode in React.

StrictMode is a tool for highlighting potential problems in an application. It does not render any visible UI. It activates additional checks and warnings for its descendants.

StrictMode currently helps with:

- Identifying components with unsafe lifecycles
- Warning about legacy string ref API usage
- Warning about deprecated findDOMNode usage
- Detecting unexpected side effects
- Detecting legacy context API

To use the `StrictMode`, you just need to wrap your component with it. Here is an example:

```jsx

import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}

```

In the above example, the `StrictMode` checks will apply to `ComponentOne` and `ComponentTwo` components but not `Header` and `Footer` components.

Please note that `StrictMode` checks are only run in development mode; they do not impact the production build.

<br>

## 9. How to prevent re-renders in React?

There are several ways to prevent unnecessary re-renders in React:

1. **ShouldComponentUpdate**: This lifecycle method can be used in class components. It allows you to control whether a component should re-render or not by returning a boolean value. If `shouldComponentUpdate` returns `false`, then the component will not re-render.

```jsx

shouldComponentUpdate(nextProps, nextState) {
  // compare with current props and state
  return nextProps.id !== this.props.id;
}

```

2. **React.PureComponent**: `PureComponent` is similar to `Component`, but it handles the `shouldComponentUpdate` method for you. When props or state changes, `PureComponent` will do a shallow comparison on both props and state. If nothing has changed, it will not trigger a re-render.

```jsx

class MyComponent extends React.PureComponent {
  // your component code
}

```

3. **React.memo**: `React.memo` is a higher order component. It's similar to `React.PureComponent` but for function components instead of classes. `React.memo` will do a shallow comparison of props and prevent re-render if props haven't changed.

```jsx

const MyComponent = React.memo(function MyComponent(props) {
  // your component code
});

```

4. **useMemo Hook**: The `useMemo` hook allows you to prevent expensive calculations on every render. It returns a memoized version of the function that only re-computes the result when one of the dependencies has changed.

```jsx

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

```

5. **useCallback Hook**: The `useCallback` hook returns a memoized version of the callback function that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.

```jsx

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

```

Remember, preventing re-renders can optimize your app, but it also adds complexity. So, use these techniques wisely and only when necessary.

<br>

## 10. How to re-render the view when the browser is resized?

In React, you can use the `window` object's `resize` event to trigger a re-render when the browser is resized. However, directly manipulating the DOM or using events like this is not the React way of doing things. Instead, you can use the `useState` and `useEffect` hooks to create a custom hook that listens for resize events. Here's an example:

```jsx

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

// Custom hook
function useWindowSize() {
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined,
  });

  useEffect(() => {
    function handleResize() {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }
    
    window.addEventListener('resize', handleResize);
    
    // Call handler right away so state gets updated with initial window size
    handleResize();
    
    // Remove event listener on cleanup
    return () => window.removeEventListener('resize', handleResize);
  }, []); // Empty array ensures that effect is only run on mount and unmount

  return windowSize;
}

function ExampleComponent() {
  const size = useWindowSize();

  return (
    <div>
      {size.width}px / {size.height}px
    </div>
  );
}

```

In this example, `useWindowSize` is a custom hook that listens for the `resize` event on the `window` object. When the window is resized, it updates the state, which causes a re-render of any component using this hook. The `ExampleComponent` uses this hook and will re-render whenever the window size changes.

<br>


> If you like this blog, you can visit my personal blog [sehgaltech](https://blog.sehgaltech.com/) for more content.