React表单onChange中setState更新状态致页面崩溃且状态未更新
问题分析与修复方案
核心错误点
- 引用旧状态导致数据错误:
onChange中处理membersId时,误用了旧状态formData.membersId,而非表单最新输入的updatedFormData.membersId,导致无法获取用户刚输入的ID集合。 - 类型转换逻辑错误:
setOptionalIds(parseInt(ids))完全不符合预期——formatMembersId返回的是ID集合(数组/类数组),parseInt仅能处理单个字符串,直接传入集合会得到NaN,而optionalIds状态期望数组类型,传入非数组值会引发状态类型混乱,直接导致页面崩溃。 - 可变变量使用不当:组件内定义的
let ids = []会在每次渲染时重置,在updatedPresentIds中直接修改它既不会触发组件更新,还会导致数据状态不一致。
修复后的代码
const RoomAttendanceComponent = () => { const [formData, setFormData] = useState({}); const [optionalIds, setOptionalIds] = useState([]); const fetchAttendanceCriteria = (updatedFormData) => updatedFormData.classRoomNo && updatedFormData.selectedDay && (formData.classRoomNo !== updatedFormData.classRoomNo || formData.selectedDay !== updatedFormData.selectedDay); const fetchAttendance = async (updatedFormData) => { const response = await fetchAttendanceData(updatedFormData); getAttendanceResults(response); setFormData(updatedFormData); }; const onChange = async ({ formData: updatedFormData, errors }) => { if (fetchAttendanceCriteria(updatedFormData)) { await fetchAttendance(updatedFormData); } if (updatedFormData.membersId) { // 使用表单最新的membersId const formattedIds = formatMembersId(updatedFormData.membersId); // 将每个ID转为十进制数字,过滤无效值后更新状态 const numericIds = formattedIds.map(id => parseInt(id, 10)).filter(id => !isNaN(id)); setOptionalIds(numericIds); } }; // 移除可变变量,直接基于当前状态计算返回值 const updatedPresentIds = (presentIds) => { if (presentIds) { return [...optionalIds, ...presentIds]; } return optionalIds; }; return ( <> <RoomAttendaceGridComponent /> <RoomAttendanceFormCompoenent /> </> ); };
额外注意事项
- 确认
formatMembersId返回的是字符串数组(如['67','6','5']),如果它返回的是Set类型,需先转为数组:Array.from(formatMembersId(updatedFormData.membersId))。 parseInt必须传入第二个参数10(指定十进制),避免出现非预期的进制解析错误。
内容的提问来源于stack exchange,提问作者Vikash Sharma
相关产品推荐
相关产品推荐

