You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useState在onClick回调内未更新值的问题排查

问题原因与解决方案

问题根源

你遇到的核心问题是组件重复挂载导致的多实例冲突:

  • 父组件(App)重新渲染时,因为没有给EditProjectDialog设置稳定的key,React会销毁旧组件并创建新组件,但通过createPortal挂载到body的旧组件DOM节点未被及时清理,页面上实际存在两个对话框实例。
  • 你输入时操作的是新组件的输入框(所以useEffect能打印更新后的值),但点击保存按钮时,实际触发的是旧组件的按钮——旧组件的project状态从未更新,因此打印的始终是原始值。
  • 之前尝试把defaultValue改成value后无法输入,也是因为旧组件的输入框覆盖在新组件之上,你实际操作的是旧组件的输入框,但旧组件的状态未同步更新。

修复步骤

1. 给对话框组件添加稳定的key

在App的条件渲染中添加key,避免组件不必要的重新挂载:

const [isEditDialogOpen, setIsEditDialogOpen] = useState(true);

return (
  {isEditDialogOpen && <EditProjectDialog key="edit-project-dialog" onClose={() => setIsEditDialogOpen(false)} />}
)

2. 改用受控组件绑定输入框

把defaultValue替换为value,确保输入框状态完全由本地project状态控制:

<input value={project.name} onChange={nameChange} />

3. 同步Redux数据更新(可选)

如果Redux中的activeProject可能在编辑过程中变化,需要用useEffect同步更新本地状态:

useEffect(() => {
  setProject(Object.assign({}, active));
}, [active]);

修复后效果

修改完成后,页面上只会保留一个EditProjectDialog实例:

  • 输入时project状态会实时更新,useEffect打印最新值。
  • 点击保存按钮时,saveProject函数能正确获取到修改后的project值。

内容的提问来源于stack exchange,提问作者Get Off My Lawn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:48:26