DEV Community

Harish G
Harish G

Posted on

Popular React Interview Questions, one needs to know. (Part 1)

1. What is a Directional data flow in react?
2. Difference between props and state in React
3. What is lifting state in react? Understand with example
4. What are Controlled and Uncontrolled componenents?
5. How the virtual DOM works in React?


1. What is a Directional data flow in react?

In React, a "directional data flow" typically refers to the way that data and information is passed through the components of a React application.

In a typical React application, data is passed from a parent component to a child component through props, which are properties that are passed to a component when it is rendered. This is known as "unidirectional data flow," because data flows in a single direction, from the parent to the child.

This unidirectional data flow helps to keep the application predictable and easy to understand, as it allows you to reason about the flow of data through the application. It also makes it easier to debug and maintain the application, as you can trace the flow of data through the components and understand how it is being used.

In some cases, you may also need to pass data from a child component back up to a parent component, or between two sibling components that are at the same level in the component hierarchy. This can be done using techniques such as callback functions or the React context API.

Here is an example of a directional data flow in a functional React component:

Imagine that you have a functional component called ChildComponent that displays a message and a form with a text input field. The message is passed to the component as a prop, and the form captures the value of the text input field when it is submitted:

import { useState } from 'react'

function ChildComponent(props) {
  const [inputValue, setInputValue] = useState('')

  const handleSubmit = (event) => {
    event.preventDefault()
    props.onFormSubmit(inputValue)
  }

  return (
    <div>
      <div>{props.message}</div>
      <form onSubmit={handleSubmit}>
        <label>
          Enter some text:
          <input type="text" value={inputValue} onChange={(event) => setInputValue(event.target.value)} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    </div>
  )
}

Enter fullscreen mode Exit fullscreen mode

The parent component, ParentComponent, can then pass the message prop and the onFormSubmit callback function to the ChildComponent when it is rendered:

import React from 'react'
import { ChildComponent } from './ChildComponent'

function ParentComponent() {
  const handleFormSubmit = (value) => {
    // do something with the value in the parent component
  }

  return (
    <ChildComponent message="Hello from the parent component!" onFormSubmit={handleFormSubmit} />
  )
}

Enter fullscreen mode Exit fullscreen mode

In the above example, the data flows from the ParentComponent to the ChildComponent, through the message prop and the onFormSubmit callback function. The ChildComponent also sends data back to the parent component through the onFormSubmit callback function, which allows the parent component to respond to a user action in the child component.


2. Difference between props and state in React

In React, props and state are both used to store and manage data within a component. However, they serve different purposes and have some key differences:

Props: Props (short for "properties") are values that are passed to a component from its parent component. Props are read-only and cannot be modified by the component that receives them. They are used to pass data down the component tree, and are commonly used to customize the behavior or appearance of a component.

State: State is an object that is used to store and manage data within a component that can change over time. Unlike props, state is mutable and can be modified by the component itself. State is used to store and manage data that is specific to a component and may change as a result of user interactions or other events.

In general, props should be used for values that are fixed or that do not change, such as configuration options or data that is passed down from a parent component. State should be used for values that may change within a component, such as the current value of a form field or the status of a toggle button.

It is important to note that components should not modify their own props, and should only use props to render their content. Any changes to the component's state or props should be made through the component's parent, which can pass the updated values down to the child component via props. This helps to maintain the unidirectional flow of data in a React application, and makes it easier to reason about and debug the component tree.


3. What is lifting state in react? Understand with example

In React, "lifting state" refers to the process of moving state that is shared between multiple components up the component tree to a common ancestor component. This allows the state to be shared and managed more efficiently, and helps to avoid redundant props or prop drilling (passing props down through multiple levels of components).

Here is an example of lifting state in React:

Imagine you have a component called ProductList that displays a list of products. Each product has a name, a price, and a "favorite" status that indicates whether the user has added it to their favorite list.

import React from 'react';

function ProductList(props) {
  const { products } = props;

  return (
    <ul>
      {products.map(product => (
        <Product
          key={product.id}
          name={product.name}
          price={product.price}
          favorite={product.favorite}
        />
      ))}
    </ul>
  );
}

Enter fullscreen mode Exit fullscreen mode

The Product component displays a single product and has a button that allows the user to toggle the product's favorite status:

import React, { useState } from 'react';

function Product(props) {
  const { name, price, favorite } = props;
  const [isFavorite, setIsFavorite] = useState(favorite);

  const handleToggleFavorite = () => {
    setIsFavorite(!isFavorite);
  };

  return (
    <li>
      <p>{name}</p>
      <p>{price}</p>
      <button onClick={handleToggleFavorite}>
        {isFavorite ? 'Remove from favorites' : 'Add to favorites'}
      </button>
    </li>
  );
}

Enter fullscreen mode Exit fullscreen mode

In this example, the favorite prop is passed down to the Product component from the ProductList component. However, if the user clicks the button to toggle the favorite status, the isFavorite state in the Product component changes. This means that the favorite prop is no longer in sync with the isFavorite state, and the component tree becomes out of sync.

To fix this, we can lift the favorite state up to the ProductList component and pass it down as a prop. The Product component can then use the favorite prop to render the button and update the prop when the button is clicked.

import React, { useState } from 'react';

function ProductList(props) {
  const { products } = props;
  const [favorites, setFavorites] = useState(new Set());

  const handleToggleFavorite = id => {
    if (favorites.has(id)) {
      favorites.delete(id);
    } else {
      favorites.add(id);
    }
    setFavorites(new Set(favorites));
  };

  return (
    <ul>
      {products.map(product => (
        <Product
          key={product.id}
          name={product.name}
          price={product.price}
          favorite={favorites.has(product.id)}
          onToggleFavorite={handleToggleFavorite}
        />
      ))}
    </ul>
  );

}

Enter fullscreen mode Exit fullscreen mode

I hope this answers the question.


4. What are Controlled and Uncontrolled componenents?

In React, a controlled component is a form element whose value is controlled by the React state. This means that the value of the form element is determined by the state, and the state is updated when the value of the form element changes.

An uncontrolled component, on the other hand, is a form element whose value is not controlled by the React state. This means that the value of the form element is determined by the element's internal state, and the React state is updated when the form element's value changes.

Here is an example of a controlled input component in React:

import React, { useState } from 'react';

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

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

  return (
    <input
      type="text"
      value={value}
      onChange={handleChange}
    />
  );
}


Enter fullscreen mode Exit fullscreen mode

In this example, the value of the input element is determined by the value state, and the state is updated when the user types into the input element.

Here is an example of an uncontrolled input component in React:

import React from 'react';

function UncontrolledInput() {
  const handleSubmit = event => {
    event.preventDefault();
    console.log(event.target.elements.input.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="input" />
      <button type="submit">Submit</button>
    </form>
  );
}


Enter fullscreen mode Exit fullscreen mode

In this example, the value of the input element is determined by the element's internal state, and the value is accessed when the form is submitted.

Controlled components are generally considered to be more predictable and easier to debug than uncontrolled components, as the state is managed by React and the component is always in sync with the state. Uncontrolled components can be useful in cases where the form element's value does not need to be tracked by the React state, or when it is not possible to use a controlled component (such as with a third-party library).


## 5. How the virtual DOM works in React?

The virtual DOM (Virtual Document Object Model) is an abstract representation of a DOM tree in memory. It is a lightweight and efficient way to update the actual DOM in a React application, and is used to minimize the number of DOM manipulations required when a component's state changes.

Here is an overview of how the virtual DOM works in React:

When a component's state changes, React creates a new virtual DOM tree that represents the updated UI.

React then compares the new virtual DOM tree to the previous virtual DOM tree, and calculates the minimum number of DOM manipulations required to update the actual DOM to match the new virtual DOM tree.

React updates the actual DOM with the minimum number of DOM manipulations required. This can include adding, deleting, or modifying DOM elements.

The updated DOM is then rendered in the browser, displaying the updated UI to the user.

Using the virtual DOM to update the actual DOM allows React to optimize performance by minimizing the number of DOM manipulations required. This is especially important in large applications with complex UI, where frequent updates to the DOM can be slow and expensive.

It is important to note that the virtual DOM is not a physical representation of the DOM, but rather an abstract representation that is used to calculate the minimum number of DOM manipulations required to update the actual DOM. The virtual DOM is not directly visible to the user, and is only used internally by React to update the actual DOM.

Here is an example of how the virtual DOM works in React, using the following component:

import React, { useState } from 'react';

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

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


Enter fullscreen mode Exit fullscreen mode

When the component is first rendered, React creates a virtual DOM tree that represents the initial UI:

{
  type: 'div',
  children: [
    {
      type: 'p',
      children: 'Count: 0'
    },
    {
      type: 'button',
      children: 'Increment'
    }
  ]
}


Enter fullscreen mode Exit fullscreen mode

When the user clicks the "Increment" button, the count state is updated and a new virtual DOM tree is created:

{
  type: 'div',
  children: [
    {
      type: 'p',
      children: 'Count: 1'
    },
    {
      type: 'button',
      children: 'Increment'
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)