我发现了这个使用单个更改函数来处理 React 和 Typescript 的多个文本输入和状态更改的聪明示例。该示例自然使用普通字符串类型:
type MyEntity = {
name: string;
// would work with any other fields
}
const handleChange = (fieldName: keyof MyEntity) => (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setValues({ ...values, [fieldName]: e.currentTarget.value });
但是,我的字符串类型是字典。例如:
{[index: string]: string}
...其中索引是语言代码字符串,其对应的值是该语言内容的字符串。例如,名称对象看起来像,name:{'en': 'Michael', 'es': 'Miguel'}
这是我当前希望为所有文本字段工作的特定于字段的更改处理程序。注意- selectedLanguage是一个字符串状态变量,带有用户选择的语言代码,为简洁起见省略。请参阅下面的代码框链接以获取完整版本):
type StringLanguage = {
[index: string] : string;
}
interface MyEntity {
name: StringLanguage;
}
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setData((prevData) => {
return {
...prevData,
name: {
...prevData.name,
[selectedLanguage]: e.target.value
}
};
});
};
这是我尝试使用与我找到的示例类似的方法。
const handleChange2 = (fieldName: keyof MyEntity) => (
e: React.ChangeEvent<HTMLInputElement>
) => {
setData((prevData) => {
return {
...prevData,
[fieldName]: {
...prevData[fieldName],
[selectedLanguage]: e.currentTarget.value
}
};
});
};
TS 在代码行上给了我错误,“ Spread types may only be created from object types.ts(2968) ”:
...prevData[fieldName]
但是 prevData 是一个对象,并且在特定于字段的版本中它可以工作。如何让这个更通用的函数与我的字典类型 StringLanguage 一起使用?:
这是文本输入的用法:
onChange={(e) => handleChange2("name")}
最后,这是一个包含我正在做的完整示例的代码框。随意注释掉代码进行实验。我已将有效的版本保持为活动状态,并从上面注释掉了无效的内容: