React+TypeScript中setState更新对象内键值报错,求解决方法
问题分析与解决
错误根源
你当前的写法有两个核心问题:
forEach方法没有返回值(返回类型是void),但setDoughQuantities的回调函数必须返回一个新的state对象,这直接导致了TypeScript的类型不匹配错误。forEach中对element的赋值只是修改了局部变量,不会改变原state对象的属性——因为element是原属性值的拷贝,而非引用。
正确写法
方法1:用Object.entries + Object.fromEntries创建新对象
这种方式更简洁,通过遍历键值对生成新对象,同时处理可选属性的undefined情况:
// 先给state定义明确的类型(可选但推荐,让类型检查更严格) type DoughQuantities = { flour: number; flour2?: number; water: number; salt: number; yeast: number; oil?: number; }; const [doughQuantities, setDoughQuantities] = useState<DoughQuantities>({ flour: doughRecipe.flour.quantity, flour2: doughRecipe.flour2?.quantity, water: doughRecipe.water.quantity, salt: doughRecipe.salt.quantity, yeast: doughRecipe.yeast.quantity, oil: doughRecipe.oil?.quantity }); useEffect(() => { if (size === 'large') { const factor = 1.5; setDoughQuantities(prev => { return Object.fromEntries( Object.entries(prev).map(([key, value]) => { // 仅对非undefined的数值乘以因子,保留原可选属性的undefined状态 return [key, value !== undefined ? value * factor : undefined]; }) ); }); } }, [size]);
方法2:展开原对象后遍历修改
如果你更习惯直接操作对象属性,可以先展开原对象创建副本,再遍历修改:
useEffect(() => { if (size === 'large') { const factor = 1.5; setDoughQuantities(prev => { // 展开原对象创建副本,避免直接修改state const newQuantities = { ...prev }; // 遍历所有键,类型断言确保TypeScript识别键的合法性 Object.keys(newQuantities).forEach(key => { const value = newQuantities[key as keyof DoughQuantities]; if (value !== undefined) { newQuantities[key as keyof DoughQuantities] = value * factor; } }); return newQuantities; }); } }, [size]);
关键注意事项
- 不可变更新:React要求state必须通过返回新对象来更新,不能直接修改
prev参数的属性,否则会导致组件不重新渲染或状态异常。 - 可选属性处理:必须判断属性值是否为
undefined,避免undefined * 1.5得到NaN,破坏状态结构。
内容的提问来源于stack exchange,提问作者Redhewlett
相关产品推荐
相关产品推荐

