Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using enumerations in React select

I want to show a dropdown in React using the following enumeration. The idea is to prevent using random strings as keys in my <select>. Keys should be constrained to Stooges.larry, Stooges.curly and Stooges.moe:

const Stooges = {
  larry: "Larry Fine",
  curly: "Curly Howard",
  moe: "Moe Howard"
};

Here's the code for my select, which works just fine:

<select value={stooge} onChange={handleChange}>
  {Object.keys(Stooges).map(key => (
    <option key={key} value={key}>
      {Stooges[key]}
    </option>
  ))}
</select>

The problem comes in when I am trying to set the initial value of the dropdown - I have to use a hard coded key:

const [stooge, setStooge] = React.useState('larry');

I can soften this a bit by picking the first key:

const keys = Object.keys(Stooges);
const [stooge, setStooge] = React.useState(keys[0]);

However, this still feels wrong. I can't tell from key[0] who am I picking.

Is there a better way to deal with enumerations in this use case? I have tried string enums in TypeScript, but they have the same issue:

enum Stooges {
  larry = "Larry Fine",
  curly = "Curly Howard",
  moe = "Moe Howard"
}

Please see my CodeSandbox here.

like image 626
Naresh Avatar asked Apr 09 '19 21:04

Naresh


1 Answers

For lack of a better solution, I have taken the following approach. I am at least able to pick the right enum by name: Stooges.larry.id:

const Stooges = {
  larry: {
    id: "larry",
    name: "Larry Fine"
  },
  curly: {
    id: "curly",
    name: "Curly Howard"
  },
  moe: {
    id: "moe",
    name: "Moe Howard"
  }
};

function App() {
  const [stooge, setStooge] = React.useState(Stooges.larry.id);

  const handleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setStooge(event.target.value);
  };

  return (
    <div className="App">
      <select value={stooge} onChange={handleChange}>
        {Object.keys(Stooges).map(key => (
          <option key={key} value={key}>
            {Stooges[key].name}
          </option>
        ))}
      </select>
    </div>
  );
}

Here's the new CodeSandbox: https://codesandbox.io/embed/wqj2q94o2k

like image 100
Naresh Avatar answered Oct 21 '22 20:10

Naresh