DEV Community

Cover image for Managing Lists, Keys, and Forms in React
John Schibelli
John Schibelli

Posted on • Edited on • Originally published at schibelli.dev

Managing Lists, Keys, and Forms in React

This article is part of the "Mastering React with Next.js: A Developer's Guide" series. In our previous article, "Event Handling & Conditional Rendering in React," we explored how to make your React applications interactive and dynamic. We covered handling events like clicks and mouse movements, as well as conditionally rendering content based on application state or user interaction. If you missed it, it’s a great starting point to understand these essential concepts.

Now, let’s dive into managing lists, keys, and forms in React. These are crucial for building dynamic forms and efficiently rendering data collections, like task lists or product catalogs.

Rendering Lists in React

Rendering lists is a common requirement in most web applications, whether it’s displaying a list of items in a shopping cart or showing search results. React makes it straightforward to handle lists, but there are a few things to keep in mind.

Basic List Rendering

You can use the map function to iterate over an array and return React elements:

import React from "react";

function ItemList({ items }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

export default ItemList;
Enter fullscreen mode Exit fullscreen mode

In this example, we use the map function to create a <li> element for each item in the items array.

The Importance of Keys

Keys are used by React to identify which items in a list have changed, been added, or removed. Without unique keys, React's rendering efficiency can degrade.

Best Practice: Use unique and stable identifiers as keys.

function ItemList({ items }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

In this example, each item has a unique id, which we use as the key.

Common Mistakes with Keys

  • Avoid Using Index as Key: Using array indices as keys can lead to issues with state and performance, especially if the list changes dynamically.

  • Ensure Key Stability: Keys should not change between renders; otherwise, React might re-render the entire list unnecessarily.

Working with Forms in React

Forms are critical for user interaction. React provides controlled and uncontrolled components for handling form inputs.

Controlled Components

In controlled components, form data is handled by React state, making it easy to validate and manipulate the input.

import React, { useState } from "react";

function LoginForm() {
  const [username, setUsername] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    alert(`Welcome, ${username}!`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input
          type="text"
          value={username}
          onChange={(e) => setUsername(e.target.value)}
        />
      </label>
      <button type="submit">Log In</button>
    </form>
  );
}

export default LoginForm;
Enter fullscreen mode Exit fullscreen mode

Here, the value of the input field is tied to the username state, and the onChange handler updates the state as the user types.

Uncontrolled Components

Uncontrolled components rely on the DOM for their current values. You can use refs to access the input value:

import React, { useRef } from "react";

function UncontrolledForm() {
  const inputRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    alert(`Input Value: ${inputRef.current.value}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input type="text" ref={inputRef} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default UncontrolledForm;
Enter fullscreen mode Exit fullscreen mode

Uncontrolled components are simpler for quick forms or when integrating with non-React libraries, but they provide less control than controlled components.

Handling Multiple Inputs

You can manage multiple inputs using a single state object:

function SignupForm() {
  const [formData, setFormData] = useState({
    username: "",
    email: "",
  });

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData((prevData) => ({
      ...prevData,
      [name]: value,
    }));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input
          type="text"
          name="username"
          value={formData.username}
          onChange={handleChange}
        />
      </label>
      <label>
        Email:
        <input
          type="email"
          name="email"
          value={formData.email}
          onChange={handleChange}
        />
      </label>
      <button type="submit">Sign Up</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here, we use the name attribute of each input to update the corresponding property in the formData state.

Tips for Success

  1. Use Unique Keys: Always use stable, unique keys for lists to help React efficiently update the DOM.

  2. Choose the Right Component Type: Use controlled components for better control and validation, and uncontrolled components for simple, less interactive forms.

  3. Handle State Carefully: For complex forms, organize state in a way that’s easy to update and validate.

Stay Connected

This wraps up our look at managing lists, keys, and forms in React. Up next, we’ll explore React’s lifecycle methods and hooks—essential tools for managing side effects and optimizing your applications.

Want to stay updated? Here’s how:

Stay tuned for the next article in the "Mastering React with Next.js: A Developer's Guide" series!

Top comments (0)