React Hook中如何修改useState对象指定属性且不影响其他原有属性
核心注意点
React 函数组件的useState更新对象状态时,不会自动合并新旧对象——传入setState的参数会完全覆盖掉之前的状态值,如果只传修改的单个属性,剩下的foo1、foo3会直接从状态中丢失。
两种不影响其他属性的修改写法
1. 推荐写法:函数式更新+展开运算符
这种写法能拿到当前最新的旧状态,避免因为闭包捕获到过期状态引发的bug,也是官方最推荐的写法:
onClick={(e) => { setState(prevState => ({ // 先把旧状态所有属性完整复制到新对象里 ...prevState, // 单独覆盖需要修改的foo2值 foo2: e.target.value })) }}
2. 简化写法:直接用当前作用域的state展开
如果能确定当前组件渲染周期内的state不会被其他异步逻辑修改,也可以直接引用当前闭包里的state变量展开,不需要写回调:
onClick={(e) => { setState({ ...state, foo2: e.target.value }) }}
这种写法的风险在于,如果组件存在异步操作连续触发更新,闭包里的state可能不是最新值,导致其他属性被旧值覆盖,生产环境优先用第一种函数式更新的写法。
修正后的完整示例代码
import React, { useState } from 'react' export const App = () => { const [state, setState] = useState({ foo1: "12", foo2: 2, foo3: null }) return ( <div> <input type="button" value="修改foo2" onClick={(e) => { setState(prev => ({ ...prev, foo2: e.target.value })) }} /> {/* 便于验证状态不丢失的展示 */} <p>foo1值:{state.foo1}</p> <p>当前foo2值:{state.foo2}</p> <p>foo3值:{state.foo3}</p> </div> ) }
内容的提问来源于stack exchange,提问作者user15455107
相关产品推荐
相关产品推荐

