React+TypeScript动态生成输入框修改同一状态对象报错解决
解决TypeScript下React动态输入框的状态索引报错问题
报错原因
你遇到的类型“string”不能用于索引类型“Object”错误,根源在于把状态value的类型定义成了Object——TypeScript的Object类型默认没有字符串索引签名,因此不允许用字符串(这里的label)去访问它的属性。
修复步骤
给状态定义正确的类型
放弃Object类型,改用Record<string, string>,它明确表示键和值都是字符串的对象,天生支持字符串索引。简化状态初始化逻辑
用Object.fromEntries替代forEach+Object.assign,一行代码就能生成符合要求的初始状态,更简洁高效。修复状态更新的覆盖问题
原代码的setValue会直接替换整个状态,导致之前输入的内容丢失。要使用展开运算符合并原有状态,只更新当前修改的字段。给input添加name属性
onChange逻辑依赖event.currentTarget.name匹配状态的键,必须给input加上name={label},否则无法正确关联对应字段。
修正后的完整代码
interface FieldProps { labels: string[] } function InputFields(props: FieldProps) { // 生成初始状态并指定类型 const initState = Object.fromEntries(props.labels.map(label => [label, ""])) const [value, setValue] = useState<Record<string, string>>(initState) const onChange = (event: React.FormEvent<HTMLInputElement>) => { const { name, value: inputValue } = event.currentTarget // 合并原有状态,仅更新当前字段 setValue(prev => ({ ...prev, [name]: inputValue })) } const renderItem = (id: number, label: string) => { return( <div> <input onChange={onChange} value={value[label]} id={id.toString()} name={label} type="text" /> </div> ) } const renderItems = () => { return props.labels.map((item, i) => renderItem(i, item)) } return ( <> <form className="grey_container-3col"> { renderItems() } </form> <br-button icon="magnifying-glass" label="Pesquisar" type="primary" onClick={()=> { // 用JSON.stringify才能正确显示对象内容 alert("State value: " + JSON.stringify(value)) }} /> </> ) }
另外补充:原代码中alert直接拼接对象会显示[object Object],改成JSON.stringify(value)才能看到实际的键值对内容。
内容的提问来源于stack exchange,提问作者kekami
相关产品推荐
相关产品推荐

