Using key prop to reset React components

Amit Merchant · July 13, 2022 ·

Sometimes, solutions to some of the problems are much simpler than we make them to be. Working with React.js is one of those things where you may complicate things unnecessarily when you don’t know the right approach.

Take the following scenario for example.

The problem

Let’s say we have a <ModalPopup> component like so.

import React, { useState } from "react";
import { FormComponent } from "./FormComponent";

export function ModalPopup() {
  const [selectedUser, setSelectedUser] = useState("");

  const users = [
    {
      id: 1,
      name: "Amit Merchant"
    },
    {
      id: 2,
      name: "John Doe"
    }
  ];

  return (
    <>
      <div>
        <label>Select a user: </label>
        <select onChange={(e) => setSelectedUser(e.target.value)}>
          <option>Select a user</option>
          {users.map((user) => (
            <option key={user.name}>{user.name}</option>
          ))}
        </select>
      </div>

      <div>
        <FormComponent name={selectedUser} />
      </div>
    </>
  );
}

As you can tell, the <ModalPopup> component renders a select menu of users. Upon selecting a user, we pass in the selectedUser to a child component called <FormComponent> that looks like so.

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

export function FormComponent({ name }) {
  const [type, setType] = useState(
    name === "John Doe" ? "Admin" : "Super Admin"
  );

  return (
    <>
      {name && (
        <div>
          <br />
          Selected user: <b>{name}</b>
          <br />
          Type: <b>{type}</b>
        </div>
      )}
    </>
  );
}

Here, in the <FormComponent> component, we are rendering the name of the selected user that we passed in as a prop from the <ModalPopup> component.

On top of this, we are also initiating an internal state for setting the type of the user using the useState hook. Notice that the value type is dependent on the name prop. So, when we select a user, the <FormComponent> component will render the name and type of the selected user. This is fine!

But the problem arises when you select another user, only the name will be rerendered and not the type. Why? That is because the internal state of the <FormComponent> component will only be initiated once when the component mounts. It doesn’t get updated when the name prop is changed.

Using the useEffect hook

To fix this, we can introduce the useEffect hook in the <FormComponent> component and update the internal state like so.

useEffect(() => {
    setType(name === "John Doe" ? "Admin" : "Super Admin");
}, [name]);

We passed in name as one of its dependencies for useEffect. So, when name is changed, the type will also be updated every time a different user is selected. Here’s everything in action.

And so, the problem is solved, right? Yes and No!

As you can tell, we have a bit of duplication going in the useEffect hook just to “reset” the internal state of the <FormComponent> component. Is there an efficient way to do this? Yes!

Enter the key prop!

Using the key prop

To immediately reset the entire component,

All we need to do is to provide a unique key prop to the component that we want to get reset. That also includes resetting the internal states of that component.

So, if we want to reset the internal state of the <FormComponent> component in our previous example, we can pass in a key prop to it like so.

<FormComponent key={selectedUser} name={selectedUser} />

And then we can remove useEffect from the <FormComponent> component entirely since the state of type will be reset everytime a new user is selected.

import React, { useState } from "react";

export function FormComponent({ name }) {
  const [type] = useState(name === "John Doe" ? "Admin" : "Super Admin");

  return (
    <>
      {name && (
        <div>
          <br />
          Selected user: <b>{name}</b>
          <br />
          Type: <b>{type}</b>
        </div>
      )}
    </>
  );
}

Here’s everything in action!

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?