React中useState的set方法未立即更新,配置useEffect依赖数组仍无效
问题根因
setFormDetails更新时未合并原有状态字段,导致更新后的formDetails丢失了初始定义的departmentIdSelected等未显式赋值的字段;- 存在冗余状态:
roleIdSelected、departmentIdSelected同时在独立状态和formDetails对象中存储,容易出现数据不同步; - React的状态更新是异步批量执行的,当前渲染周期内的状态值始终是固定的,调用
setState后立刻读取当前闭包中的状态,拿到的必然是更新前的旧值。
解决方案
方案1:直接在数据获取逻辑中处理(最简便)
不需要依赖formDetails的更新触发后续逻辑,拿到接口返回的person数据后直接计算部门ID,完全避开异步更新的问题:
const getRunPerson = (id) =>{ const person = getPerson(id); // 拿到person数据后直接计算部门ID,不用等状态更新 const roleEntity = getRole(person.roleId); setDepartmentIdSelected(roleEntity.DepartmentId); // 更新formDetails时合并旧状态,避免字段丢失 setFormDetails(prev => ({ ...prev, firstName:person.fname, lastName : person.lname, roleIdSelected : person.roleId, })); setRoleIdSelected(person.roleId); }
调整后可以删除原来监听formDetails的useEffect,避免重复执行。
方案2:调整useEffect依赖精度
如果必须通过状态变更触发后续逻辑,直接监听formDetails.roleIdSelected,同时保证状态更新时合并旧值:
// 更新时合并旧状态 const getRunPerson = (id) =>{ const person = getPerson(id); setFormDetails(prev => ({ ...prev, firstName:person.fname, lastName : person.lname, roleIdSelected : person.roleId, })); setRoleIdSelected(person.roleId); } // 只监听需要的字段,避免无关变更触发,也减少对象浅比较带来的异常 useEffect(()=>{ if(idPerson !== "new" && formDetails.roleIdSelected){ const roleEntity = getRole(formDetails.roleIdSelected); setDepartmentIdSelected(roleEntity.DepartmentId); } },[idPerson, formDetails.roleIdSelected])
优化建议
移除冗余的独立状态roleIdSelected和departmentIdSelected,统一使用formDetails中的对应字段存储,避免多源状态同步带来的bug,选择组件的value直接绑定formDetails.departmentIdSelected即可。
内容的提问来源于stack exchange,提问作者klau
相关产品推荐
相关产品推荐

