HomeGorakh Raj Joshi

React Interview Questions

List of common questions asked in interview

  • #Interview

1. What is JSX? 🌟

JSX stands for JavaScript XML and it is an XML-like syntax extension to ECMAScript. Basically, it just provides the syntactic sugar for the `React.createElement(type, props, ...children)` function, giving us expressiveness of JavaScript along with HTML like template syntax.

In the example below, the text inside `<h1>` tag is returned as a JavaScript function to the render function.

export default function App() {
  return <h1 className="greeting">{'Hello, this is a JSX Code!'}</h1>;
}

2. What is the difference between Element and Component? 🌟

In React, the terms "Element" and "Component" are both fundamental concepts but refer to slightly different things.

Element:

  • An element in React is a plain JavaScript object representing a virtual representation of a DOM node or component. It describes what you want to see on the screen.
  • Elements are lightweight and are typically the objects you return from components when rendering UI.
  • Elements are created using JSX syntax or `React.createElement()` calls.

For example, a simple JSX element like `<div>Hello, world!</div>` gets compiled down to a `React.createElement('div', null, 'Hello, world!')` call, which creates a React element representing a `<div>` with the text content "Hello, world!".

Component:

  • A component is a JavaScript class or function that optionally accepts input (called props) and returns a React element tree.
  • Components are the building blocks of a React application. They encapsulate logic and rendering behavior.
  • Components can be either class components (ES6 classes) or functional components (JavaScript functions). With React Hooks, functional components can also have state and lifecycle methods.
  • Components can compose other components, allowing you to build complex UIs from simpler reusable pieces.

For example, a simple functional component looks like this:

function Greeting(props) {
  return <div>Hello, {props.name}!</div>;
}

Here, `Greeting` is a component that takes `name` as a prop and renders a `<div>` element with a greeting message.

In summary:

  • An element is a plain JavaScript object that describes what you want to render.
  • A component is a function or class that produces React elements and manages them. Components can be reused and composed together to build complex UIs.

3. How to create components in React? 🌟

Components are the building blocks of creating User Interfaces (UI) in React. There are two possible ways to create a component.

  • Function Components: This is the simplest way to create a component. Those are pure JavaScript functions that accept props object as the first parameter and return React elements to render the output:
function Greeting({ message }) {
  return <h1>{`Hello, ${message}`}</h1>;
}
  • Class Components: You can also use ES6 class to define a component. The above function component can be written as a class component:
class Greeting extends React.Component {
  render() {
    return <h1>{`Hello, ${this.props.message}`}</h1>;
  }
}

4. When to use a Class Component over a Function Component? 🌟

It is recommended to use Functional component if you are starting from scratch. Functional and class components have distinct use cases, and understanding their differences is crucial for optimal usage. Class components may still be preferable, especially in older codebases not fully embracing Hooks yet.

Functional Components in React vs. Class Components

Simplicity:
Functional components are JavaScript functions, making them easier to write, understand, and test. They are concise and don't use `this`, resulting in cleaner code.

Hooks:
Introduced in React 16.8, Hooks enable state and other features in functional components, previously limited to class components. This complexity can be achieved without classes.

Performance:
Functional components are lightweight and perform better than class components due to reduced overhead, enhancing application performance.

Improved Readability:
Functional components, especially with Hooks, promote readable and maintainable code by encouraging the use of pure functions.

Lifecycle Method Simplification:
The `useEffect` Hook simplifies lifecycle management in functional components by consolidating lifecycle logic into a single API.

5. What is the difference between state and props? 🌟

In React, the main difference between state and props is that:

  • State is managed within a component and can be updated using `setState()`. It represents the internal state of the component and can change over time due to user actions or network responses.

  • Props (short for properties) are passed to a component from its parent and are immutable within the component. They are used to provide component configuration based on its parent's data or environment.

In summary, state is internal and mutable, controlled by the component itself, while props are external and immutable, controlled by the component's parent.

6. Why should we not update the state directly? 🧩

Updating state directly can cause React to miss the state change and not re-render the component, or use an outdated or incorrect state value. To avoid these problems, you should use setState() or useState() methods, and follow the best practices of creating a new object or array when updating state, and using a function when updating state based on the previous state.

7. What is the purpose of a callback function as an argument of `setState()`? πŸš€

When you call setState() in React, the state update does not happen immediately synchronously. React batches state updates for performance reasons. This means that after calling setState(), React schedules an update and continues with its own internal processes without waiting for the state to be actually updated.

By providing a callback function to setState(), you ensure that the callback is executed only after React has finished applying the state update. This allows you to work with the most up-to-date state values inside the callback function.

import React, { useState } from 'react';

const MyComponent = () => {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1, () => {
      console.log('Count updated:', count); // Callback executed after state update
    });
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default MyComponent;

In this example, the callback provided to `setCount()` is invoked after `count` has been updated, allowing you to perform actions based on the updated state.

8. What is the use of refs? 🧩

Refs in React are a powerful tool when used judiciously. They offer direct access to DOM elements and provide a way to persist values without causing rerenders. However, it’s crucial to use them in harmony with React’s declarative nature.

https://codedamn.com/news/reactjs/what-are-refs-in-react-js-and-when-should-you-use-them

9. How to pass a parameter to an event handler or callback? 🧩

In a functional component in React, when you want to pass parameters to an event handler or callback function, you typically need to use a technique to create a function that captures those parameters and then passes them along when the event occurs. This is because directly calling a function with parameters inside JSX can cause the function to be invoked immediately on render, which is not the desired behavior for event handlers.

Here's how you can pass parameters to an event handler in a functional component:

import React from 'react';

const MyComponent = () => {
  // Define a function that takes additional parameters
  const handleClick = (param) => {
    console.log(`Button clicked with parameter: ${param}`);
    // Do something with the parameter
  };

  return (
    <div>
      {/* Use an arrow function to pass parameters */}
      <button onClick={() => handleClick('Hello')}>Click me</button>
    </div>
  );
};

export default MyComponent;

10. What are synthetic events in React? 🧩

In React, a synthetic event is an abstraction layer that React provides to handle events in a consistent and cross-browser-compatible manner. Synthetic events are not native DOM events; instead, they are JavaScript objects that wrap native events. React does this to ensure that event handling is consistent across different browsers and to provide additional features like event pooling for performance optimization. React uses a mechanism called "event delegation" to improve performance.

When you use React to handle events, such as onClick, onChange, or onSubmit, you typically pass a function as the event handler. React will then automatically create a synthetic event object and pass it to your event handler function.

Here's an example of how you can use synthetic events in React:

import React from 'react';

class MyComponent extends React.Component {
  handleClick = (event) => {
    // Access properties from the synthetic event
    console.log('Button clicked');
    console.log('Event type:', event.type);
    console.log('Mouse coordinates:', event.clientX, event.clientY);
  };

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

export default MyComponent;

11. What is "key" prop and what is the benefit of using it in arrays of elements? 🌟

A `key` is a special attribute you should include when mapping over arrays to render data. Key prop helps React identify which items have changed, are added, or are removed.

Keys should be unique among its siblings. Most often we use ID from our data as key:

const todoItems = todos.map((todo) => <li key={todo.id}>{todo.text}</li>);

When you don't have stable IDs for rendered items, you may use the item index as a key as a last resort:

const todoItems = todos.map((todo, index) => <li key={index}>{todo.text}</li>);

Note:

  • Using indexes for keys is not recommended if the order of items may change. This can negatively impact performance and may cause issues with component state.
  • If you extract list item as a separate component then apply keys on the list component instead of `li` tag.
  • There will be a warning message in the console if the `key` prop is not present on list items.
  • The key attribute accepts either a string or number and internally converts it to a string type.

12. How to create refs? 🌟

In React, you can create refs using the `useRef` hook for functional components or by using the `createRef` method for class components.

For functional components with hooks:

import React, { useRef } from 'react';

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

  // Use myRef in your component
  return <div ref={myRef}>Hello, Ref!</div>;
}

For class components:

import React, { Component } from 'react';

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

  render() {
    // Use this.myRef in your component
    return <div ref={this.myRef}>Hello, Ref!</div>;
  }
}

In both cases, the `ref` attribute is used to attach the ref to a DOM element or a React component instance, allowing you to interact with the underlying DOM or component programmatically.

13. What are forward refs? 🧩

Forward refs in React provide a way to pass a ref from a parent component down to a child component, allowing the parent to interact with the child's DOM node or React component instance directly.

To use forward refs, you typically create a ref in the parent component and then pass that ref down to a child component. The child component can "forward" this ref to a specific DOM element or component within its own render function.

Here's a modern example of how to use forward refs:

// ChildComponent.js
import React from 'react';

// Child component that forwards the ref to a specific DOM element
const ChildComponent = React.forwardRef((props, ref) => {
  return <input ref={ref} />;
});

export default ChildComponent;
// ParentComponent.js
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';

const ParentComponent = () => {
  const inputRef = useRef(null);

  // Access the input element's focus method from the parent component
  const focusInput = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };

  return (
    <div>
      {/* Forward the ref to the ChildComponent */}
      <ChildComponent ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};

export default ParentComponent;

In this example:

  • `ChildComponent` uses `React.forwardRef` to create a new component that can accept a ref and forward it to an underlying DOM element (`<input>` in this case).
  • `ParentComponent` renders `ChildComponent` and creates a `useRef` hook (`inputRef`) to hold a reference to the input element inside `ChildComponent`.
  • When the "Focus Input" button is clicked, the `focusInput` function in `ParentComponent` is triggered, which uses `inputRef.current` to access and call the `focus` method of the input element inside `ChildComponent`.

Using forward refs allows you to maintain encapsulation and still have control over the child's DOM or component instance from the parent component when needed.

14. What is Virtual DOM? 🌟

The Virtual DOM in React is a lightweight copy of the actual DOM (Document Object Model) representation. React uses this Virtual DOM to optimize updates to the real DOM that is rendered in the browser.

Here's how it works:

  • Virtual DOM Structure: When you render a React component, React creates a virtual representation of the DOM in memory. This representation includes all the elements, attributes, and their hierarchies as JavaScript objects.

  • Efficient Reconciliation: Whenever there is a change in the component's state or props, React creates a new virtual DOM representation of the component.

  • Diffing Algorithm: React then compares this new virtual DOM with the previous one using a process called "diffing." It efficiently identifies what parts of the actual DOM have changed.

  • Minimal DOM Updates: By knowing which parts of the DOM have changed, React calculates the most efficient way to update the actual DOM to match the new virtual DOM. Instead of re-rendering the entire DOM tree, React only updates the necessary parts.

  • Batched Updates: React may batch multiple updates together and apply them in a single DOM operation for performance reasons. This batching is possible because all updates are first applied to the virtual DOM.

  • Render to Browser: Finally, React updates the real DOM to reflect the changes made in the virtual DOM. This updating process is optimized and minimizes direct interaction with the browser DOM, which can be costly in terms of performance.

The Virtual DOM helps React achieve high performance by reducing the number of direct DOM manipulations and making updates more efficient. This approach is a key factor in React's popularity and is one of the reasons React applications can handle dynamic data and user interactions smoothly.

15. What is the difference between Shadow DOM and Virtual DOM? πŸš€

The Shadow DOM is a browser technology designed primarily for scoping variables and CSS in web components. The Virtual DOM is a concept implemented by libraries in JavaScript on top of browser APIs.

16. What is React Fiber? 🧩

React Fiber is an internal reimplementation of the React core algorithm. It is designed to enable better scheduling, prioritization, and interruption of rendering updates. Fiber allows React to break down rendering work into smaller units (or fibers) that can be paused, aborted, or resumed, which ultimately improves performance and responsiveness, especially for complex and interactive user interfaces. This new architecture introduced in React 16 allows React to handle concurrent updates more efficiently and supports features like suspense for data fetching and lazy loading.

17. What are controlled and cncontrolled components? 🌟

In React, controlled and uncontrolled elements refer to how form elements (like `<input>`, `<textarea>`, and `<select>`) manage their state and handle user input:

  • Controlled Components:

    • Controlled components are those where React controls the state of the form elements.

    • The component's state is kept in sync with the input elements by using React state and handling onChange events.

    • Changes to the input elements are handled through state updates, and the current value of the input is always controlled by React.

    • Example:

      const [value, setValue] = useState('');
      
      const handleChange = (event) => {
        setValue(event.target.value);
      };
      
      return <input type="text" value={value} onChange={handleChange} />;
      
  • Uncontrolled Components:

    • Uncontrolled components allow the DOM to maintain the state of the form elements.

    • The state of the input elements is managed by the DOM itself, not by React state.

    • You can still access the current value using refs after rendering to interact with the DOM directly.

    • Example:

      const inputRef = useRef(null);
      
      const handleClick = () => {
        const value = inputRef.current.value;
        console.log(value);
      };
      
      return (
        <>
          <input type="text" ref={inputRef} />
          <button onClick={handleClick}>Get Value</button>
        </>
      );
      

In summary, controlled components have React managing the state of form elements through component state and event handlers, while uncontrolled components delegate state management to the DOM and provide access to DOM nodes using refs for direct manipulation when needed. Controlled components are often preferred in React applications because they provide a single source of truth for form element values and make it easier to implement complex UI behaviors.

18. What is reconciliation? 🧩

Reconciliation in React refers to the process of updating the DOM to match the most recent React element tree. When changes occur in a React component (due to state or props updates), React compares the new element tree with the previous one to determine what changes need to be applied to the actual DOM.

Here's a concise breakdown of reconciliation in React:

  • Element Tree Comparison:

    • React maintains a virtual representation of the DOM called the Virtual DOM.
    • When a component updates, React creates a new element tree based on the updated state or props.
  • Diffing Algorithm:

    • React performs a process known as "diffing" to efficiently compare the new element tree with the previous one.
    • It identifies which parts of the virtual DOM have changed.
  • Minimal Updates:

    • After identifying the differences, React calculates the minimal set of changes needed to update the actual DOM to reflect the new element tree.
    • This minimizes unnecessary updates and improves performance by only updating what has changed.
  • Reconciliation Process:

    • React applies these changes to the real DOM through a process called reconciliation.
    • The goal is to synchronize the DOM with the current state of the React component tree efficiently.

In summary, reconciliation is the process by which React updates the browser's DOM to reflect changes in the React component tree. It optimizes performance by selectively updating only the necessary parts of the DOM based on the differences between the old and new component states. This process is a key part of React's efficient rendering and ensures that the UI remains in sync with the application's state.

19. How to set state with a dynamic key name? 🧩

To set state with a dynamic key name in React, you can use the ES6 computed property name syntax inside an object. This allows you to dynamically compute the key name based on a variable or an expression. Here's how you can do it:

import React, { useState } from 'react';

const MyComponent = () => {
  const [state, setState] = useState({});

  const handleInputChange = (key, value) => {
    // Create a new state object using the spread operator to copy existing state
    setState((prevState) => ({
      ...prevState,
      [key]: value, // Use computed property name to set state with dynamic key
    }));
  };

  return (
    <div>
      <input
        type="text"
        value={state.firstName || ''}
        onChange={(e) => handleInputChange('firstName', e.target.value)}
        placeholder="First Name"
      />
      <input
        type="text"
        value={state.lastName || ''}
        onChange={(e) => handleInputChange('lastName', e.target.value)}
        placeholder="Last Name"
      />
      {/* You can add more input fields similarly */}
    </div>
  );
};

export default MyComponent;

In the example above:

  • We have a functional component `MyComponent` that uses the `useState` hook to maintain a state object (`state`) with dynamic keys.
  • The `handleInputChange` function takes two parameters: `key` (the dynamic key name) and `value` (the value to set for that key).
  • Inside `handleInputChange`, we use the spread operator (`...prevState`) to create a new object that copies the existing state.
  • We then use the computed property name syntax (`[key]: value`) to dynamically set the state with the specified key and value.
  • In the JSX, each `<input>` element is associated with a specific key (`'firstName'`, `'lastName'`, etc.), and the `onChange` event handler calls `handleInputChange` with the appropriate key and the input's current value (`e.target.value`).

This pattern allows you to set state with dynamic keys based on user input or any other dynamic source, making your React component more flexible and reusable.

20. What would be the common mistake of a function being called every time the component renders? 🧩

A common mistake that leads to a function being called every time a component renders in React is directly invoking the function inside the component body, especially for event handlers or other callbacks. This behavior can result in unnecessary function executions on each render, which can impact performance negatively.

Here's an example to illustrate this mistake:

import React from 'react';

const MyComponent = () => {
  const handleClick = () => {
    console.log('Button clicked!');
  };

  return (
    <div>
      <button onClick={handleClick}>Click me</button>
    </div>
  );
};

export default MyComponent;

In the above code:

  • The `handleClick` function is defined inside the `MyComponent` functional component.
  • Each time `MyComponent` renders (due to state or prop changes), a new instance of `handleClick` is created.
  • This means that every time the `<button>` is rendered (which is part of `MyComponent`), it receives a new `onClick` event handler, even if the function logic remains the same.

To avoid this mistake and optimize performance:

  • Use `useCallback` Hook:

    • If the function depends on props or state and needs to be memoized, use the `useCallback` hook to memoize the function and prevent unnecessary re-creation on each render.
    import React, { useCallback } from 'react';
    
    const MyComponent = () => {
      const handleClick = useCallback(() => {
        console.log('Button clicked!');
      }, []); // Empty dependency array means the function won't change
    
      return (
        <div>
          <button onClick={handleClick}>Click me</button>
        </div>
      );
    };
    
    export default MyComponent;
    
  • Use Inline Arrow Functions Sparingly:

    • Avoid using inline arrow functions directly inside JSX for event handlers, especially if they are complex or depend on props/state.
    import React from 'react';
    
    const MyComponent = () => {
      const handleClick = () => {
        console.log('Button clicked!');
      };
    
      return (
        <div>
          {/* Using inline arrow function sparingly */}
          <button onClick={() => handleClick()}>Click me</button>
        </div>
      );
    };
    
    export default MyComponent;
    

By addressing this common mistake, you can ensure that functions are not needlessly re-created on each render, leading to better performance and more efficient React components. Use hooks like `useCallback` to optimize function creation and consider the dependencies that affect the function's behavior.

21. Is lazy function supports named exports? 🧩

No, the `React.lazy` function in React does not directly support named exports. It is designed to work with default exports (`export default ...`) when dynamically importing components.

Example:

// MyComponent.js
const MyComponent = () => {
  return <div>Hello Lazy Component!</div>;
};

export default MyComponent;
// App.js
import React, { Suspense } from 'react';

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

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

export default App;

In this example, `React.lazy` imports `MyComponent` as a default export (`export default MyComponent;`), and it's loaded lazily using `<LazyComponent />`.

For named exports (`export const ...`), you would typically import and use them directly rather than using `React.lazy` for lazy loading. Example:

// NamedComponent.js
export const NamedComponent1 = () => {
  return <div>Named Component 1</div>;
};

// App.js
import React from 'react';
import { NamedComponent1 } from './NamedComponent';

const App = () => {
  return (
    <div>
      <NamedComponent1 />
    </div>
  );
};

export default App;

Here, `NamedComponent1` is imported directly from its module (`import { NamedComponent1 } from './NamedComponent';`) and used within the `App` component without lazy loading.

22. Why React uses `className` over `class` attribute? 🌟

The attribute `class` is a keyword in JavaScript, and JSX is an extension of JavaScript. That's the principle reason why React uses `className` instead of `class`.

23. What are fragments? 🌟

Fragments are a common pattern in React used to return multiple elements from a component without adding extra nodes to the DOM. They provide a way to group a list of children elements. There are two syntaxes for using fragments: `<Fragment>` or the shorter syntax `<>...</>`.

Example of using fragments inside a `Story` component:

function Story({ title, description, date }) {
  return (
    <>
      <h2>{title}</h2>
      <p>{description}</p>
      <p>{date}</p>
    </>
  );
}

Rendering a list of fragments inside a loop with a `key` attribute:

function StoryBook() {
  return stories.map((story) => (
    <Fragment key={story.id}>
      <h2>{story.title}</h2>
      <p>{story.description}</p>
      <p>{story.date}</p>
    </Fragment>
  ));
}

Usually, the shorter syntax (`<>...</>`) is preferred unless a `key` attribute is required.

24. Why are fragments better than container divs? 🌟

Fragments offer several advantages over container divs:

  • Fragments are faster and use less memory by not creating an extra DOM node.
  • They help maintain the desired layout with CSS mechanisms like Flexbox and CSS Grid.
  • Fragments keep the DOM Inspector less cluttered by not adding unnecessary parent nodes.

25. What are portals in React? 🧩

Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. This is useful for scenarios like modal dialogs or tooltips where the content needs to be rendered outside of the current component's DOM tree.

Example usage of `ReactDOM.createPortal`:

ReactDOM.createPortal(child, container);

26. What are stateless components? 🧩

Stateless components (also known as functional components) in React are components that do not manage state. They are simple functions that take props as input and return what should be rendered. Stateless components are easy to write, understand, and test.

Example of a stateless functional component:

function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

27. What are stateful components? 🧩

Stateful components (also known as class components or components with hooks) are components that manage their own state. They use the `state` object to keep track of data that may change over time. Stateful components can handle user interactions, data fetching, and more.

Example of a stateful functional component with hooks:

import React, { useState } from 'react';

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

  const handleIncrement = () => {
    setCount(count + 1);
  };

  return (
    <>
      <button onClick={handleIncrement}>Increment</button>
      <span>Counter: {count}</span>
    </>
  );
}

28. How to apply validation on props in React? 🌟

In React, you can apply validation on props using `propTypes`. `propTypes` allows you to define the type of each prop expected by a component and whether it is required or not.

Example using class components:

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

class User extends React.Component {
  static propTypes = {
    name: PropTypes.string.isRequired,
    age: PropTypes.number.isRequired,
  };

  render() {
    return (
      <>
        <h1>{`Welcome, ${this.props.name}`}</h1>
        <h2>{`Age, ${this.props.age}`}</h2>
      </>
    );
  }
}

Example using functional components:

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

function User({ name, age }) {
  return (
    <>
      <h1>{`Welcome, ${name}`}</h1>
      <h2>{`Age, ${age}`}</h2>
    </>
  );
}

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

29. What will happen if you use props in initial state? 🧩

In React components, using props in the initial state directly is not recommended. This is because React initializes the component state only once, when the component is created, based on the initial state provided. After that, any changes to the props won't be reflected in the state.

Instead, you should use props directly where needed in your component, and if you need to update the state based on props changes, you can use the `useEffect` hook. This hook allows you to execute code in response to changes in props or other values.

Here's a concise example:

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

function MyComponent(props) {
  // Initialize state using props directly (not recommended):
  const [state, setState] = useState({
    data: props.initialData,
  });

  // Use useEffect to update state when props change:
  useEffect(() => {
    setState({ data: props.initialData });
  }, [props.initialData]);

  return (
    <div>
      <p>Data: {state.data}</p>
    </div>
  );
}

export default MyComponent;

In this example, instead of initializing the state directly with `props.initialData`, we use `useEffect` to update the state whenever `props.initialData` changes. This way, the state is kept in sync with the props.

30. How do you conditionally render components? 🧩

Conditional rendering in React allows you to render different components or content based on certain conditions. JSX itself supports conditional rendering using JavaScript expressions.

Using logical `&&` operator for conditional rendering:

const MyComponent = ({ name, address }) => (
  <div>
    <h2>{name}</h2>
    {address && <p>{address}</p>} {/* Render address only if it exists */}
  </div>
);

Using ternary operator for more complex conditions:

const MyComponent = ({ name, address }) => (
  <div>
    <h2>{name}</h2>
    {address ? <p>{address}</p> : <p>{'Address is not available'}</p>}
  </div>
);

31. Why do we need to be careful when spreading props on DOM elements? 🧩

We need to be careful when spreading props (`...props`) onto DOM elements in React for a couple of reasons:

  • Unintended DOM Attribute Propagation: When you use `...props` to spread props onto a DOM element like `<div {...props} />`, you are essentially passing all props (including custom props) as attributes to the HTML element. This can lead to unexpected behavior if these props are not intended to be HTML attributes. For example, if you pass down a custom prop like `customProp="value"` and then spread `...props` onto a `<div>`, React will attempt to add `customProp="value"` as a DOM attribute, which is invalid HTML and can cause warnings or errors.

  • Potential Security Risks: Spreading props directly onto DOM elements can also pose security risks if the props contain sensitive data or are not properly sanitized. For instance, if a malicious user manages to inject a malicious script into a prop value, spreading props onto the DOM element without validation could lead to a cross-site scripting (XSS) vulnerability.

To mitigate these issues, it's important to be selective and deliberate when spreading props onto DOM elements:

  • Filter and Pass Relevant Props: Instead of spreading all props (`...props`), explicitly pass down only the props that are intended to be used as DOM attributes. For example:

    function MyComponent({ className, style, ...otherProps }) {
      return <div className={className} style={style} {...otherProps} />;
    }
    

    Here, `className` and `style` are explicitly handled, while `otherProps` (the remaining props) are spread onto the `<div>`.

  • Sanitize and Validate Props: Ensure that props containing user-generated content are properly sanitized and validated before being used as attributes on DOM elements. Use appropriate libraries or methods to handle potentially unsafe content to prevent XSS attacks.

By being mindful of how props are spread onto DOM elements and following best practices for prop handling, we can write more secure and predictable React components.

32. How do you use decorators in React? πŸš€

Decorators provide a clean and readable way to modify the functionality of a component. Although not part of the standard JavaScript (ES6/ES7), they can be used with transpilers like Babel.

Example of using a decorator to set the document title for a component:

const setTitle = (title) => (WrappedComponent) => {
  return class extends React.Component {
    componentDidMount() {
      document.title = title;
    }

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

@setTitle('Profile')
class Profile extends React.Component {
  // Component code...
}

The `Profile` component will have its document title set to 'Profile' when mounted.

33. How do you memoize a component? 🧩

Memoization in React helps optimize rendering by caching the result of a component's render method based on its props. React provides `React.memo` as a higher-order component to memoize functional components.

Example using `React.memo`:

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

// or export default directly with memoization
export default React.memo(MyFunctionComponent);

`React.memo` checks the props of the component and re-renders only if the props have changed, optimizing performance.

34. What is a switching component? 🧩

A switching component is a component designed to render one of many possible components based on a specific prop value or condition. This pattern is useful for conditional rendering where different components need to be displayed based on certain criteria.

For example, consider a switching component that displays different pages based on a `page` prop value:

import HomePage from './HomePage';
import AboutPage from './AboutPage';
import ServicesPage from './ServicesPage';
import ContactPage from './ContactPage';

const PAGES = {
  home: HomePage,
  about: AboutPage,
  services: ServicesPage,
  contact: ContactPage,
};

const Page = (props) => {
  const Handler = PAGES[props.page] || ContactPage;

  return <Handler {...props} />;
};

Page.propTypes = {
  page: PropTypes.oneOf(Object.keys(PAGES)).isRequired,
};

Here, the `Page` component dynamically renders the appropriate page component (`Handler`) based on the `page` prop value. This approach leverages an object (`PAGES`) to map prop values to specific components, enabling flexible rendering based on external data.

35. Why is `isMounted()` an anti-pattern and what is the proper solution? 🧩

`isMounted()` is considered an anti-pattern in React because it introduces unreliable state checks into component code. The primary use of `isMounted()` was to prevent `setState()` calls on unmounted components, which could lead to memory leaks and potential bugs.

Example usage of `isMounted()`:

if (this.isMounted()) {
  this.setState({ ... });
}

Instead of relying on `isMounted()`, React encourages using proper lifecycle methods to manage component state and subscriptions. For example, you can cancel subscriptions or clear timeouts in `componentWillUnmount()` to ensure that the component cleans up after itself when it unmounts.

componentWillUnmount() {
  // Cleanup operations (e.g., clear timeouts, unsubscribe)
}

By utilizing lifecycle methods correctly, you can avoid the need for `isMounted()` checks and ensure a more predictable component behavior.

36. What are the Pointer Events supported in React? 🧩

Pointer Events provide a unified way to handle all input events across various devices, such as mouse, touch surfaces, or pens. These events are supported in React DOM and can be used for handling user interactions. Here's a list of available pointer event types in React:

  • `onPointerDown`
  • `onPointerMove`
  • `onPointerUp`
  • `onPointerCancel`
  • `onGotPointerCapture`
  • `onLostPointerCapture`
  • `onPointerEnter`
  • `onPointerLeave`
  • `onPointerOver`
  • `onPointerOut`

These events enable you to build components that respond to different types of input interactions from users, making your applications more versatile across devices.

37. Why should component names start with a capital letter? 🌟

In React, component names must start with a capital letter when they are used in JSX. This convention helps React differentiate between user-defined components and regular HTML/SVG elements.

For example, if you define a component named `MyComponent`, you should use it in JSX like this:

<MyComponent />

React will recognize `MyComponent` as a component class rather than an HTML tag due to the capitalization of the name.

However, there are some exceptions where lowercase component names are valid, such as when using property accessors (e.g., `<obj.component />`). Additionally, when importing a component defined with a lowercase name, you should capitalize it:

import MyComponent from './MyComponent';

This convention ensures clarity and consistency in your React codebase.

38. Are custom DOM attributes supported in React v16? 🧩

Yes, starting from React v16, custom DOM attributes are supported. Previously, React used to ignore unknown DOM attributes, but in React v16 and later, any unknown attributes provided in JSX will be added to the rendered DOM elements.

For example:

<div myCustomAttribute={'something'} />

In React v16, this would render as:

<div myCustomAttribute="something" />

This change allows developers to integrate with third-party libraries, experiment with new DOM APIs, and use browser-specific attributes more freely within React applications.

39. What is the difference between `super()` and `super(props)` in React using ES6 classes? 🧩

In React ES6 class components, `super()` and `super(props)` are used in the constructor to call the constructor of the parent class (i.e., `React.Component`). The difference lies in whether you need to access `this.props` inside the constructor.

  • Using `super(props)`:

    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        console.log(this.props); // Access to props
      }
    }
    

    Here, `super(props)` initializes `this.props` before the constructor code runs, allowing you to access `this.props` inside the constructor.

  • Using `super()`:

    class MyComponent extends React.Component {
      constructor(props) {
        super();
        console.log(this.props); // undefined
      }
    }
    

    Using `super()` without passing `props` will still work outside the constructor, but `this.props` will be `undefined` inside the constructor.

Outside the constructor, both forms of `super()` will behave the same in terms of accessing `this.props`.

These are important considerations when initializing component state or setting up event listeners in the constructor.

40. How to loop inside JSX? 🧩

To iterate over an array and render JSX elements for each item, use `Array.prototype.map` directly within JSX. This allows you to dynamically generate components based on array data.

Example:

<tbody>
  {items.map((item) => (
    <SomeComponent key={item.id} name={item.name} />
  ))}
</tbody>

In JSX, you cannot use traditional `for` loops directly, as JSX requires expressions enclosed in curly braces `{}` to evaluate JavaScript expressions.

41. How to conditionally apply class attributes? 🌟

To conditionally apply CSS classes based on component props or state, you can use JavaScript expressions within JSX. Concatenation or template literals are commonly used to conditionally include class names.

Example using concatenation:

<div className={'btn-panel ' + (this.props.visible ? 'show' : 'hidden')}>Button Panel</div>

Example using template literals:

<div className={`btn-panel ${this.props.visible ? 'show' : 'hidden'}`}>Button Panel</div>

This approach allows you to dynamically apply classes based on component logic, such as toggling visibility or applying different styles based on state.

42. What is the difference between React and ReactDOM? 🌟

The separation of `react` and `react-dom` into separate packages was a strategic decision by the React team to allow for greater flexibility and broader platform support.

  • `react` Package:

    • Contains fundamental React APIs like `React.createElement()`, `React.Component`, and `React.Children`.
    • Provides core functionality for defining components, creating elements, and managing component lifecycles.
    • These APIs are essential for building React components and managing the virtual DOM.
  • `react-dom` Package:

    • Includes APIs specifically related to rendering React components in the DOM.
    • Provides `ReactDOM.render()` for mounting React components into the DOM.

By splitting these functionalities into separate packages (`react` for core React logic and `react-dom` for DOM-specific rendering), the React team enabled the creation of alternative renderers like `react-native` (for mobile) and `react-three` (for 3D graphics). This modular architecture promotes code reuse and supports React's vision of being a universal framework for different platforms.

43. Why is ReactDOM separated from React? 🧩

The separation of `ReactDOM` from the core `React` library reflects React's philosophy of being a framework that can target diverse environments beyond just web browsers. Here are key reasons for this separation:

  • Platform Agnostic Components:

    • By isolating DOM-specific features in `ReactDOM`, React components can be used across different platforms like web, mobile (React Native), and even VR/AR environments (React 360).
  • Code Modularity and Extensibility:

    • Separation allows developers to build custom renderers for specific platforms (e.g., `react-dom`, `react-native`, `react-three`), which are tailored to the unique characteristics of each environment.
  • Reduced Bundle Size:

    • Developers can optimize bundle sizes by importing only the necessary modules (`react` for core logic, `react-dom` for web rendering) based on the target platform.

This separation empowers developers to write once and deploy across multiple platforms, ensuring a consistent development experience while leveraging the specific capabilities of each target environment.

44. How to use React label element? 🌟

When using the `<label>` element in JSX to associate it with a form control, you should use the `htmlFor` attribute instead of `for` due to `for` being a reserved keyword in JavaScript. This ensures proper binding and accessibility.

Incorrect usage:

<label for={'user'}>{'User'}</label>
<input type={'text'} id={'user'} />

Correct usage:

<label htmlFor={'user'}>{'User'}</label>
<input type={'text'} id={'user'} />

By using `htmlFor`, React ensures that the label correctly associates with the specified input element, maintaining accessibility standards.

45. How to combine multiple inline style objects? 🧩

In regular React, you can combine multiple inline style objects using the spread (`...`) operator within JSX:

<button style={{ ...styles.panel.button, ...styles.panel.submitButton }}>{'Submit'}</button>

This technique merges multiple style objects (`styles.panel.button` and `styles.panel.submitButton`) into a single style object for the `<button>` element.

46. How to re-render the view when the browser is resized? πŸš€

To update the view dynamically when the browser is resized, you can use React hooks (`useState` and `useEffect`) to manage the component's state and listen for the `resize` event.

Example using hooks:

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

function WindowDimensions() {
  const [dimensions, setDimensions] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    function handleResize() {
      setDimensions({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    }

    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // Empty dependency array to run effect only once

  return (
    <span>
      {dimensions.width} x {dimensions.height}
    </span>
  );
}

This example creates a component that displays the window's dimensions and updates them dynamically when the window is resized. The `useEffect` hook adds and removes the `resize` event listener, ensuring efficient resource management.

47. What is the difference between `setState()` and `replaceState()` methods? πŸš€

When you use `setState()`, the current and previous states are merged. On the other hand, `replaceState()` throws out the current state and replaces it with only what you provide. Typically, `setState()` is preferred unless you specifically need to remove all previous keys for some reason. You can also set state to `false`/`null` in `setState()` instead of using `replaceState()`.

48. How to listen to state changes?

To listen to state changes, you can utilize the `componentDidUpdate` lifecycle method, which is called after state updates. Within this method, you can compare the provided `prevProps` and `prevState` with the current `props` and `state` to determine if something meaningful has changed.

componentDidUpdate(prevProps, prevState) {
  // Compare prevProps and prevState with current props and state
  // Determine if any significant changes have occurred
}

The recommended approach for removing an array element in React state is to use the `Array.prototype.filter()` method. This method creates a new array that includes elements based on a provided condition, effectively excluding the element you want to remove.

removeItem(index) {
  this.setState({
    data: this.state.data.filter((item, i) => i !== index)
  });
}

50. Is it possible to use React without rendering HTML? 🧩

Yes, it is possible to use React without rendering HTML by returning different types of values from the `render()` method based on your requirements. This includes returning `false`, `true`, `null`, an empty array (`[]`), an empty string (`""`), or using `<React.Fragment>` or `<>` in newer versions of React.

51. How to pretty print JSON with React? 🧩

To pretty print JSON with React while retaining formatting, you can use the `<pre>` tag along with `JSON.stringify()` inside your component's `render()` method.

const data = { name: 'John', age: 42 };

class User extends React.Component {
  render() {
    return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

51. Why can't you update props in React? 🧩

In React, props are designed to be immutable and top-down. This means that a parent component can pass any prop values to its child components, but the child components cannot modify the props received from their parent. This approach ensures predictable data flow and helps maintain the integrity of data throughout the component hierarchy.

52. How to focus an input element on page load? 🧩

You can focus an input element on page load by using a ref and the `componentDidMount()` lifecycle method in class components, or the `useEffect()` hook in functional components (for React versions 16.8 and above).

class App extends React.Component {
  componentDidMount() {
    this.nameInput.focus();
  }

  render() {
    return (
      <div>
        <input defaultValue={"Won't focus"} />
        <input ref={(input) => (this.nameInput = input)} defaultValue={'Will focus'} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
import React, { useEffect, useRef } from 'react';

const App = () => {
  const inputElRef = useRef(null);

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

  return (
    <div>
      <input defaultValue={"Won't focus"} />
      <input ref={inputElRef} defaultValue={'Will focus'} />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('app'));

53. What are the possible ways of updating objects in state? 🧩

There are two common ways of updating objects in React state:

  • Using `setState()` with an object to merge with state:

    • Using `Object.assign()` or the spread operator to create a copy of the object and update specific properties.
    const user = Object.assign({}, this.state.user, { age: 42 });
    this.setState({ user });
    
    const user = { ...this.state.user, age: 42 };
    this.setState({ user });
    
  • Using `setState()` with a function:

    • Pass a function to `setState()` that receives the previous state as an argument and returns an updated state object.
    this.setState((prevState) => ({
      user: {
        ...prevState.user,
        age: 42,
      },
    }));
    

54. How can we find the version of React at runtime in the browser? 🌟

To find the version of React at runtime in the browser, you can access the `React.version` property.

const REACT_VERSION = React.version;

ReactDOM.render(<div>{`React version: ${REACT_VERSION}`}</div>, document.getElementById('app'));

55. How to update a component every second? 🧩

You can update a component every second by using `setInterval()` inside the `componentDidMount()` lifecycle method to trigger the state update, and remember to clear the interval in the `componentWillUnmount()` lifecycle method to prevent memory leaks.

componentDidMount() {
  this.interval = setInterval(() => this.setState({ time: Date.now() }), 1000);
}

componentWillUnmount() {
  clearInterval(this.interval);
}

56. How do you apply vendor prefixes to inline styles in React? 🧩

React does not apply vendor prefixes automatically. You need to manually add vendor prefixes to inline styles when necessary.

<div
  style={{
    transform: 'rotate(90deg)',
    WebkitTransform: 'rotate(90deg)', // For Webkit browsers like Safari
    msTransform: 'rotate(90deg)', // For Internet Explorer
  }}
/>

57. How to import and export components using React and ES6? 🌟

To import and export components using React and ES6, you can use the `export default` syntax.

import React from 'react';
import User from 'user';

export default class MyProfile extends React.Component {
  render() {
    return <User type="customer">//...</User>;
  }
}

58. How to programmatically trigger click event in React? 🧩

In React, you can programmatically trigger a click event on a DOM element using refs. Here’s a step-by-step guide on how to do this:

  • Create a Ref for the DOM Element: First, you need to create a ref that will reference the DOM element on which you want to trigger the click event. You can create a ref using the `useRef` hook.

    import React, { useRef } from 'react';
    
    const MyComponent = () => {
      const buttonRef = useRef(null);
    
      const handleClick = () => {
        console.log('Button Clicked!');
      };
    
      return (
        <button ref={buttonRef} onClick={handleClick}>
          Click me
        </button>
      );
    };
    
    export default MyComponent;
    
  • Trigger Click Programmatically: Once you have the ref set up, you can use this ref to access the DOM element and trigger a click event on it programmatically.

    import React, { useRef, useEffect } from 'react';
    
    const MyComponent = () => {
      const buttonRef = useRef(null);
    
      const handleClick = () => {
        console.log('Button Clicked!');
      };
    
      useEffect(() => {
        // Access the button element using the ref
        const buttonElement = buttonRef.current;
    
        // Trigger a click event on the button element
        buttonElement.click();
      }, []);
    
      return (
        <button ref={buttonRef} onClick={handleClick}>
          Click me
        </button>
      );
    };
    
    export default MyComponent;
    

In this example:

  • We define a functional component `MyComponent` which contains a button element.
  • We use the `useRef` hook to create a ref named `buttonRef` which will refer to the button DOM element.
  • Inside the component, we define a `handleClick` function that logs a message to the console when the button is clicked.
  • We use the `useEffect` hook with an empty dependency array (`[]`) to run the click operation only once when the component mounts.
  • Inside the `useEffect`, we access the DOM element referenced by `buttonRef.current` and call the `click()` method on it to trigger a click event programmatically.

Make sure that the ref is properly attached to the button element (`<button ref={buttonRef}...`) and that the click event is handled (`onClick={handleClick}`). This approach allows you to simulate a button click programmatically within a React component.

59. What are the common folder structures for React? 🧩

There are two common practices for structuring React projects: grouping by features/routes or grouping by file type.

Grouping by features/routes:


common/
β”œβ”€ Avatar.js
β”œβ”€ Avatar.css
β”œβ”€ APIUtils.js
└─ APIUtils.test.js
feed/
β”œβ”€ index.js
β”œβ”€ Feed.js
β”œβ”€ Feed.css
β”œβ”€ FeedStory.js
β”œβ”€ FeedStory.test.js
└─ FeedAPI.js
profile/
β”œβ”€ index.js
β”œβ”€ Profile.js
β”œβ”€ ProfileHeader.js
β”œβ”€ ProfileHeader.css
└─ ProfileAPI.js

Grouping by file type:


api/
β”œβ”€ APIUtils.js
β”œβ”€ APIUtils.test.js
β”œβ”€ ProfileAPI.js
└─ UserAPI.js
components/
β”œβ”€ Avatar.js
β”œβ”€ Avatar.css
β”œβ”€ Feed.js
β”œβ”€ Feed.css
β”œβ”€ FeedStory.js
β”œβ”€ FeedStory.test.js
β”œβ”€ Profile.js
β”œβ”€ ProfileHeader.js
└─ ProfileHeader.css

60. What are render props? 🧩

Render props is a technique for sharing code between React components using a prop whose value is a function. This allows components to take in a function as a prop and invoke that function with necessary data to render dynamic content.

<DataProvider render={(data) => <h1>{`Hello ${data.target}`}</h1>} />

Libraries like React Router and DownShift utilize render props to enable flexible and composable component behaviors.

61. Explain about types of side effects in React component.

There are two types of side effects in React component. They are:

Effects without Cleanup: This side effect will be used in useEffect which does not restrict the browser from screen update. It also improves the responsiveness of an application. A few common examples are network requests, Logging, manual DOM mutations, etc.

Effects with Cleanup: Some of the Hook effects will require the cleanup after updating of DOM is done. For example, if you want to set up an external data source subscription, it requires cleaning up the memory else there might be a problem of memory leak. It is a known fact that React will carry out the cleanup of memory when the unmounting of components happens. But the effects will run for each render() method rather than for any specific method. Thus we can say that, before execution of the effects succeeding time the React will also cleanup effects from the preceding render.

61. What are error boundaries?

An error boundary is a React component designed to catch JavaScript errors in its child component tree during rendering, lifecycle methods, or in the constructor, and handle them gracefully without causing the entire application to crash.

Any component that defines either or both of the lifecycle methods `static getDerivedStateFromError(error)` or `componentDidCatch(error, errorInfo)` is considered an error boundary.

An error boundary can detect errors in the following places:

  • Render Phase: Errors that occur during the rendering of a component.
  • Inside a Lifecycle Method: Errors that happen within lifecycle methods such as `componentDidMount`, `componentDidUpdate`, etc.
  • Inside the Constructor: Errors that occur during component initialization.

Without using error boundaries, errors occurring in components can lead to the unmounting of the component and potentially render a blank page, disrupting the user experience.

In your provided example, the `CounterComponent` throws an error if the `counterValue` reaches 2 inside the `render` method. Without an error boundary, this error would lead to the unmounting of `CounterComponent`.

To implement an error boundary:

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

  static getDerivedStateFromError(error) {
    // Update state to indicate an error has occurred
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // Log the error to an error tracking service
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // Fallback UI when there's an error
      return <h4>Something went wrong</h4>;
    }
    // Render children components normally
    return this.props.children;
  }
}

Now, you can use the `ErrorBoundary` component to wrap around `CounterComponent` to catch and handle any errors that occur within `CounterComponent`:

<ErrorBoundary>
  <CounterComponent />
</ErrorBoundary>

With this setup, if an error occurs within `CounterComponent`β€”for example, if `counterValue` becomes 2β€”the error will be caught by the `ErrorBoundary`, preventing the entire application from crashing. The `ErrorBoundary` can then display a fallback UI (e.g., "Something went wrong") to inform the user of the error, providing a smoother and more resilient user experience.

61. What are Custom Hooks?

Custom Hooks in JavaScript are functions that start with 'use' and allow you to reuse stateful logic across React components. They were introduced in React v16.8 as part of the hook feature.

Here's a simple example of a custom hook:

import { useState } from 'react';

// Custom hook for handling a boolean toggle
function useToggle(initialValue) {
  const [value, setValue] = useState(initialValue);

  const toggle = () => {
    setValue(!value);
  };

  return [value, toggle];
}

// Example usage of the custom hook
function App() {
  const [isOn, toggleIsOn] = useToggle(false);

  return (
    <div>
      <button onClick={toggleIsOn}>{isOn ? 'ON' : 'OFF'}</button>
    </div>
  );
}

In this example:

  • `useToggle` is a custom hook that encapsulates the logic for a simple boolean toggle.
  • It uses the `useState` hook internally to manage the toggle state.
  • The `useToggle` hook returns an array containing the current boolean value (`value`) and a function (`toggle`) to toggle the boolean value.
  • In the `App` component, `useToggle` is used to manage the state (`isOn`) and toggle function (`toggleIsOn`).
  • Clicking the button toggles the `isOn` state between `true` and `false`, updating the button label accordingly.

Custom hooks allow you to extract and reuse complex logic across different components, promoting code reusability and reducing repetition. They are a powerful addition to React functional components.

Gorakh Raj Joshi

Senior Fullstack Engineer: Specializing in System Design and Architecture, Accessibility, and Frontend Interface Design

LinkedIn

GitHub

Email

All rights reserved Β© Gorakh Raj Joshi 2024