ReactStars组件CRUD编辑时useState重置为初始状态问题
问题描述
开发人员CRUD功能,人员包含skills数组(每个元素含skill字符串和stars整数),已实现Bootstrap模态框内动态增删改技能输入框功能。从Firebase获取数据正常,但关闭模态框后重新打开,索引0的stars会重置为初始值0。
组件结构:EditPerson -> ModalEditSkills -> SkillEdit
问题原因
ModalEditSkills向SkillEdit传递的是原始未修改的data,而非模态框内编辑后的newData,导致每次打开模态框时,SkillEdit会重新加载原始数据覆盖修改内容。SkillEdit初始inputField状态为[{ skill: "", stars: 0 }],当data未正确同步时,会触发初始值覆盖已有数据。
解决方案
1. 修正ModalEditSkills的props传递
将传递给SkillEdit的data替换为newData,确保打开模态框时加载上次编辑后的状态:
// ModalEditSkills.jsx - Modal.Body部分 <Modal.Body> <SkillEdit data={newData} setNewData={setNewData} /> </Modal.Body>
2. 优化SkillEdit的useEffect逻辑
仅当data为有效数组时更新inputField,避免初始值干扰:
// SkillEdit.jsx useEffect(() => { if (Array.isArray(data) && data.length > 0) { setInputField([...data]); // 浅拷贝避免引用关联问题 } }, [data]);
3. 统一ModalEditSkills的newData初始类型
将newData初始值设为数组,与skills类型保持一致:
// ModalEditSkills.jsx const [newData, setNewData] = useState([]);
4. 简化EditPerson的状态层级
去掉冗余的skills状态,直接通过data.skills传递,减少状态同步问题:
// EditPerson.jsx const EditPerson = () => { const [data, setData] = useState({ skills: [] }); const { id } = useParams(); useEffect(() => { if (id) { const fetchData = async () => { const docRef = doc(db, "person", id); try { const docSnap = await getDoc(docRef); setData(docSnap.data() || { skills: [] }); } catch (error) { console.log(error); } }; fetchData().catch(console.error); } else { setData({ skills: [] }); } }, [id]); const handleSkills = (updatedSkills) => { setData(prev => ({ ...prev, skills: updatedSkills })); }; return ( <div> <ModalEditSkills handleSkills={handleSkills} data={data.skills} /> </div> ); }
验证效果
修改后,关闭模态框再打开时,SkillEdit会加载ModalEditSkills中保存的newData状态,索引0的stars值不再被重置,同时状态流转更清晰,避免冗余状态导致的异常。
内容的提问来源于stack exchange,提问作者Alexander Simonsen
相关产品推荐
相关产品推荐

