reactjs - Använda uppräkningar i React-select
Jag vill visa en dropdown i React med följande uppräkning. Idén är att förhindra att använda slumpmässiga strängar som nycklar i min <select>. Nycklarna bör begränsas till Stooges.larry, Stooges.curly och Stooges.moe:
const Stooges = {
larry: "Larry Fine",
curly: "Curly Howard",
moe: "Moe Howard"
};
Här är koden för mitt val, som fungerar alldeles utmärkt:
<select value={stooge} onChange={handleChange}>
{Object.keys(Stooges).map(key => (
<option key={key} value={key}>
{Stooges[key]}
</option>
))}
</select>
Problemet uppstår när jag försöker ställa in startvärdet för rullgardinsmenyn - jag måste använda en hårdkodad nyckel:
const [stooge, setStooge] = React.useState('larry');
Jag kan mjuka upp detta lite genom att välja den första nyckeln:
const keys = Object.keys(Stooges);
const [stooge, setStooge] = React.useState(keys[0]);
Men det här känns fortfarande fel. Jag kan inte avgöra från key[0] vem jag väljer.
Finns det ett bättre sätt att hantera uppräkningar i detta användningsfall? Jag har försökt med strängenumereringar i TypeScript, men de har samma problem:
enum Stooges {
larry = "Larry Fine",
curly = "Curly Howard",
moe = "Moe Howard"
}
Vänligen se min CodeSandbox här.
Svar #1
För en enum Animals:
enum Animal{
Cat= "Cat",
Dog= "Dog",
Hamster= "Hamster"
}
Vi kan definiera en generisk funktion getEnumKeys som hämtar arrayen av nycklar i en enum:
// Inspired from https://github.com/microsoft/TypeScript/issues/30611#issuecomment-570773496
function getEnumKeys<
T extends string,
TEnumValue extends string | number,
>(enumVariable: { [key in T]: TEnumValue }) {
return Object.keys(enumVariable) as Array<T>;
}
Vi kan sedan gå igenom listan över nycklar för Animal som returneras av getEnumKeys-funktionen i select.
import React from "react";
enum Animal {
Cat = "Cat",
Dog = "Dog",
Hamster = "Hamster"
}
export default function App() {
const [currentAnimal, setCurrentAnimal] = React.useState<Animal>(Animal.Cat);
return (
<select
value={currentAnimal}
onChange={(e) => {
setCurrentAnimal(Animal[e.target.value as keyof typeof Animal]);
}}
>
{getEnumKeys(Animal).map((key, index) => (
<option key={index} value={Animal[key]}>
{key}
</option>
))}
</select>
);
}
function getEnumKeys<
T extends string,
TEnumValue extends string | number,
>(enumVariable: { [key in T]: TEnumValue }) {
return Object.keys(enumVariable) as Array<T>;
}
Kod Sandlåda: https://codesandbox.io/s/unruffled-sinoussi-pr7dpf?file=/src/App.tsx:0-600
Svar #2
I brist på en bättre lösning har jag tagit följande tillvägagångssätt. Jag kan åtminstone välja rätt enum efter namn: 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>
);
}
Här är den nya CodeSandbox: https://codesandbox.io/embed/wqj2q94o2k
