Nar*_*esh 6 enums typescript reactjs
我想使用以下枚举在 React 中显示一个下拉列表。这个想法是为了防止使用随机字符串作为我的<select>
. 键应限制为Stooges.larry
,Stooges.curly
和Stooges.moe
:
const Stooges = {
larry: "Larry Fine",
curly: "Curly Howard",
moe: "Moe Howard"
};
Run Code Online (Sandbox Code Playgroud)
这是我选择的代码,它工作得很好:
<select value={stooge} onChange={handleChange}>
{Object.keys(Stooges).map(key => (
<option key={key} value={key}>
{Stooges[key]}
</option>
))}
</select>
Run Code Online (Sandbox Code Playgroud)
当我尝试设置下拉列表的初始值时出现问题 - 我必须使用硬编码键:
const [stooge, setStooge] = React.useState('larry');
Run Code Online (Sandbox Code Playgroud)
我可以通过选择第一个键来软化这一点:
const keys = Object.keys(Stooges);
const [stooge, setStooge] = React.useState(keys[0]);
Run Code Online (Sandbox Code Playgroud)
然而,这仍然感觉不对。我不知道key[0]
我在挑选谁。
在这个用例中有没有更好的方法来处理枚举?我在 TypeScript 中尝试过字符串枚举,但它们有同样的问题:
enum Stooges {
larry = "Larry Fine",
curly = "Curly Howard",
moe = "Moe Howard"
}
Run Code Online (Sandbox Code Playgroud)
请在此处查看我的 CodeSandbox 。
小智 9
对于枚举Animals
:
enum Animal{
Cat= "Cat",
Dog= "Dog",
Hamster= "Hamster"
}
Run Code Online (Sandbox Code Playgroud)
我们可以定义一个通用函数getEnumKeys
,它获取枚举的键数组:
// 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>;
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以映射select 中函数Animal
返回的键列表。getEnumKeys
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>;
}
Run Code Online (Sandbox Code Playgroud)
代码沙箱:https://codesandbox.io/s/unruffled-sinoussi-pr7dpf? file=/src/App.tsx:0-600
由于缺乏更好的解决方案,我采取了以下方法。我至少能够通过名称选择正确的枚举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>
);
}
Run Code Online (Sandbox Code Playgroud)
这是新的 CodeSandbox:https ://codesandbox.io/embed/wqj2q94o2k