React useState设默认值时input onChange不触发状态重渲染
问题根因
核心错误是把JSX React元素直接存入了组件状态。
- 当你不给
useState传初始值时,editfield初始值为undefined,传给input的value={undefined}会被React识别为非受控组件,输入时DOM自身会更新显示值,属于“碰巧看起来正常”,实际上状态和输入值并没有正确绑定。 - 当你传入
post.body作为初始值后,input成为严格受控组件,而你存在postbody状态里的JSX,是调用editPost那一刻通过闭包捕获的旧editfield值。后续editfield更新触发重渲染时,存在state里的JSX不会自动同步新的状态值,input拿到的永远是旧的固定值,自然输入时不会更新。
正确修复方式
永远不要把JSX元素存在组件state里,state只存最基础的业务状态数据,JSX结构直接在组件渲染阶段输出,保证每次重渲染都能拿到最新的状态值:
// 仅存基础业务状态,不存JSX const [isEditing, setIsEditing] = React.useState(false); const [editfield, setEdit_field] = React.useState(post.body); function updateField(event) { setEdit_field(event.target.value); } function editPost() { setIsEditing(true); } // 渲染时直接根据状态拼装结构 return ( <> {/* 原有页面其他逻辑 */} {isEditing ? ( <div> <input onChange={updateField} value={editfield} /> </div> ) : ( <div> <p>{post.body}</p> <button onClick={editPost}>编辑</button> </div> )} </> )
不推荐的兜底方案:如果一定要把JSX存在state中,需要在
editfield每次变化时同步调用setPostbody传入带最新editfield值的JSX,这种写法会产生大量冗余状态、极易触发闭包问题,没有实际使用价值。
内容的提问来源于stack exchange,提问作者Mohammad Fadi Al-Nahhas
相关产品推荐
相关产品推荐

