Top React Developer Interview Questions

author image Hirely
at 08 Jan, 2025

Question: How do you handle forms in React?

Answer:

Handling forms in React involves managing user input, validating data, and submitting the form. React uses two main approaches for managing form state:

  1. Uncontrolled Components (using refs)
  2. Controlled Components (using React state)

Most commonly, controlled components are used in React, as they provide more control over the form data and allow React to manage the form state.

Let’s break down both approaches:


1. Controlled Components

In controlled components, the form data is managed by the component’s state. React “controls” the form by setting the value of the input fields to be derived from the state. This gives you full control over the form’s behavior and validation.

Key Concepts:

  • Each input field (like input, textarea, select) has a value prop that is controlled by the React state.
  • An event handler (like onChange) updates the state whenever the user types in the input field.

Example of a Controlled Component:

import React, { useState } from 'react';

const ControlledForm = () => {
  // Defining state variables for form fields
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  // Handling the form submission
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('Form submitted with:', { name, email });
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          type="text"
          value={name} // Controlled input: value bound to state
          onChange={(e) => setName(e.target.value)} // Update state on change
        />
      </label>
      <br />
      <label>
        Email:
        <input
          type="email"
          value={email} // Controlled input: value bound to state
          onChange={(e) => setEmail(e.target.value)} // Update state on change
        />
      </label>
      <br />
      <button type="submit">Submit</button>
    </form>
  );
};

export default ControlledForm;

Explanation:

  • State Management: The form’s fields (like name and email) are controlled through the state (useState in this case). The values of the input fields are bound to the state values.
  • onChange Handlers: Each input field has an onChange handler that updates the corresponding state when the user types in the input fields.
  • Form Submission: When the form is submitted, the form data is logged or processed as required. The handleSubmit function is called on form submission.

Advantages of Controlled Components:

  • One Source of Truth: The form data is stored in the component state, making it easy to manage, validate, and update.
  • Easy Validation: You can easily validate or manipulate the form data within the React component before submission.
  • Event Handling: You can attach event listeners like onChange to every input field, giving you full control over user input.

2. Uncontrolled Components

In uncontrolled components, the form data is handled by the DOM itself, and React does not directly manage the form’s state. You can use the ref attribute to access the values of the form elements directly.

Example of an Uncontrolled Component:

import React, { useRef } from 'react';

const UncontrolledForm = () => {
  // Using refs to access form elements
  const nameRef = useRef();
  const emailRef = useRef();

  // Handling the form submission
  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('Form submitted with:', {
      name: nameRef.current.value,
      email: emailRef.current.value,
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          type="text"
          ref={nameRef} // Uncontrolled input: value accessed via ref
        />
      </label>
      <br />
      <label>
        Email:
        <input
          type="email"
          ref={emailRef} // Uncontrolled input: value accessed via ref
        />
      </label>
      <br />
      <button type="submit">Submit</button>
    </form>
  );
};

export default UncontrolledForm;

Explanation:

  • Refs: We use useRef() to create references (nameRef and emailRef) for the input fields. These references are used to directly access the DOM elements and their current values.
  • Form Submission: When the form is submitted, the values are extracted using nameRef.current.value and emailRef.current.value.

Advantages of Uncontrolled Components:

  • Less Overhead: No need to manage state for each form element, which can be useful for simple forms or when you need to interact with the DOM directly.
  • More Like Traditional HTML Forms: If you’re migrating from traditional JavaScript forms or integrating with third-party libraries that require direct DOM manipulation, uncontrolled components can be a simpler choice.

Form Validation in React

Form validation is typically done within the form’s event handlers (e.g., handleSubmit). You can validate each field before submitting, and if a field is invalid, you can display error messages.

Example of Form Validation in a Controlled Component:

import React, { useState } from 'react';

const ValidatedForm = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [errors, setErrors] = useState({});

  const validateForm = () => {
    let formErrors = {};
    if (!name) formErrors.name = "Name is required";
    if (!email) formErrors.email = "Email is required";
    else if (!/\S+@\S+\.\S+/.test(email)) formErrors.email = "Email is invalid";
    return formErrors;
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    const formErrors = validateForm();
    if (Object.keys(formErrors).length === 0) {
      console.log('Form submitted with:', { name, email });
    } else {
      setErrors(formErrors);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
        />
        {errors.name && <div style={{ color: 'red' }}>{errors.name}</div>}
      </label>
      <br />
      <label>
        Email:
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        {errors.email && <div style={{ color: 'red' }}>{errors.email}</div>}
      </label>
      <br />
      <button type="submit">Submit</button>
    </form>
  );
};

export default ValidatedForm;

Explanation:

  • Validation: The validateForm function checks if the fields are filled and if the email is in a valid format.
  • Error Handling: If there are validation errors, they are stored in the errors state and displayed next to the relevant input fields.

Handling Form Submission:

Once the form data is validated, you can submit it using an event handler, such as handleSubmit, and process it (e.g., send it to a server using fetch or axios).

Key Takeaways:

  1. Controlled Components: Preferred in React for managing form data using component state. Provides more control over the input data, validation, and submission.
  2. Uncontrolled Components: Useful for simple forms where you don’t need to manage the form state or need to interact with the DOM directly.
  3. Validation: React allows easy validation by using state and conditional rendering to show error messages.
  4. Form Submission: Once the form is validated, it can be submitted, and the data can be processed or sent to a backend.

Using controlled components is recommended for most React applications, as they provide more flexibility and better integration with the React component lifecycle.

Question: What is the key prop in React and why is it important?

Answer:

The key prop in React is a special attribute used to help React identify which items in a list are changed, added, or removed. This helps React optimize the process of updating the UI by ensuring that only the necessary elements are re-rendered.

In React, when rendering a list of elements (e.g., in a map function), each element needs a unique identifier so that React can efficiently update and manage the DOM. The key prop provides this unique identifier.

Why is the key prop important?

  1. Efficient Reconciliation: When React re-renders a component, it uses the key to identify which elements have changed. If the key is not provided or is incorrect, React may not be able to optimize the update process, leading to unnecessary re-renders or incorrect updates.
  2. Maintaining State Across Re-renders: If you have dynamic lists where individual items may change (e.g., in a to-do list or a list of user comments), the key ensures that React can correctly associate the state and properties of the items between re-renders.
  3. Performance Optimization: By using keys, React can minimize the number of DOM updates, leading to better performance when dealing with large lists or frequently updated lists.

How does the key prop work?

  • Uniqueness: The value of the key must be unique among siblings (i.e., within the same list).
  • Stable: The key should be stable across renders. Using array indices as keys (e.g., index in a map) is discouraged in most cases because the order of items may change, leading to potential issues with reordering, performance, and state preservation.

Example of Using the key Prop:

import React from 'react';

const TodoList = ({ todos }) => {
  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li> // Using a unique `id` as the key
      ))}
    </ul>
  );
};

export default TodoList;

In this example:

  • Each todo item is assigned a unique key prop based on its id. This allows React to keep track of each item and efficiently update the list when items are added, removed, or reordered.

Why not use the index as the key?

Although you can use the array index as a key (e.g., key={index}), it’s generally discouraged unless the list is static and will not change dynamically. This is because:

  • If items are added, removed, or reordered, React may reuse the same DOM elements incorrectly, which can lead to visual bugs or issues with input field values, animations, and component states.
  • Using indices as keys may cause problems if the list is dynamic because React can misinterpret which elements were added or removed, leading to inefficient updates.

Example Problem with Using Array Index as Key:

const TodoList = ({ todos }) => {
  return (
    <ul>
      {todos.map((todo, index) => (
        <li key={index}>{todo.text}</li> // Using the index as the key
      ))}
    </ul>
  );
};

In this case, if the order of todos changes (e.g., if an item is added or removed in the middle of the list), React will mistakenly assume the items haven’t changed, potentially leading to UI issues or loss of state (e.g., an input field losing its value).

What Makes a Good Key?

  • Unique: The key should be unique for each item in the list, which helps React differentiate between them.
  • Stable: The key should not change over time unless the actual item changes. Avoid using values like random numbers or timestamps as keys.
  • Consistent: Ideally, use a property that is guaranteed to stay consistent, such as a database-generated id or a unique identifier from the data.

Best Practices for Using the key Prop:

  • Use a unique identifier (such as id) from the data as the key whenever possible.
  • Avoid using array indices as keys unless the list is static and will not change during the lifecycle of the component.
  • Ensure that the key value remains stable over re-renders to maintain the correct identity of the elements.

Conclusion:

The key prop in React is crucial for optimizing rendering performance, ensuring correct UI updates, and maintaining the consistency of the component state during re-renders. By providing a unique and stable key for each item in a list, React can efficiently reconcile changes and minimize unnecessary DOM updates, improving the performance and correctness of your application.

Read More

If you can’t get enough from this article, Aihirely has plenty more related information, such as ReactJS interview questions, ReactJS interview experiences, and details about various ReactJS job positions. Click here to check it out.

Related Posts

Trace Job opportunities

Hirely, your exclusive interview companion, empowers your competence and facilitates your interviews.

Get Started Now