Search code examples
htmlreactjsreact-hookshtml-select

How to manage state for multiple Select components in React


I am trying to create a schedule table where employees can be assigned for different days using the React Select component. But, I am not sure how to manage each of their states individually as currently, they all take the same value when I change one option. Any sort of guidance will be appreciated. Should I track each state separately? Wouldn't that get cumbersome?

Here is my Table component:


import React from "react";
import Select from "react-select";
import { useState } from "react";

const options = [
  { value: "None", label: "None" },
  { value: "X1", label: "X1" },
  { value: "X2", label: "X2" },
  { value: "X3", label: "X3" },
  { value: "X4", label: "X4" },
  { value: "X5", label: "X5" },
  { value: "X6", label: "X6" },
];

const headers = ["", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"];
const columns = [
  "Morning Up Stairs",
  "Morning Down Stairs",
  "Morning Parking Lot",
  "Lunch A",
  "Lunch B",
  "Lunch C",
  "Lunch D",
  "Afternoon Up Stairs",
  "Afternoon Down Stairs",
  "Afternoon Parking Lot",
];

const Scheduler = () => {
  const [selectedOption, setSelectedOption] = useState(null);

  const handleSelectChange = (selectedOption, rowId, header, colName) => {
    setSelectedOption(selectedOption)
    console.log(`Selected option: ${selectedOption.value}`);
    console.log(`Row ID: ${rowId}`);
    console.log(`Column name: ${colName}`);
  };

  return (
    <div>
      <table>
        <thead>
          <tr>
            {headers.map((header) => (
              <th key={header}>{header}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {columns.map((colName, index) => (
            <tr key={index}>
              <td>{colName}</td>
              {headers.map(
                (header, index) =>
                  index > 0 && (
                    <td key={index}>
                      <Select
                        options={options}
                        value={selectedOption}
                        onChange={(selectedOption) =>
                          handleSelectChange(
                            selectedOption,
                            index,
                            header,
                            colName
                          )
                        }
                      />
                    </td>
                  )
              )}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

This is how it looks currently: Same value


Solution

  • You'll need to create a component for individual day select lists, and has state in this individual day component.

    Have a look at this: https://codesandbox.io/s/cocky-waterfall-pi918n?file=/src/index.js