React Native:过滤后的数组无法将值传递至useState的问题解决求助
解决React useState未接收Firestore异步数据的问题
我一眼就看出问题所在了——你的编辑状态只在组件初始化时赋值了一次,但Firestore的数据是异步加载的,第一次渲染时medicine还是空数组,所以editMedicineName这些状态初始值都是空,后续数据加载完成后也没有触发状态更新。
问题根源
组件初始化流程:
medicine初始值是[],所以过滤后的medicineStock也是空数组useState(medicineStock.map(...).toString())会生成空字符串,并且这个初始化逻辑只会执行一次- 等
onSnapshot拿到Firestore的数据更新medicine后,medicineStock变成了有数据的数组,但编辑状态不会自动跟着变,因为没有触发更新逻辑
解决方案:监听数据变化同步状态
我们可以添加一个useEffect,监听medicineStock的变化,当它有数据时,把对应的值同步到编辑状态里。同时优化数据取值逻辑(过滤后应该只有一个元素,不用map,直接取第一个元素更高效)。
修改后的完整代码:
function EditMedicine() { const { medicineId } = useParams(); const [medicine, setMedicine] = useState([]); useEffect(() => { const q = query(collection(db, 'medicine'), where("isAccepted", "==", true) ) onSnapshot(q, (querySnapshot) => { setMedicine(querySnapshot.docs.map(doc => ({ id: doc.id, data: doc.data() }))) }) },[]) // 优化:用find直接获取单个匹配元素,替代filter返回数组 const medicineStock = medicine.find(item => item.id === medicineId); // 编辑状态初始值设为空字符串即可 const [editMedicineName, setEditMedicineName] = useState(""); const [editMedicineRegNo, setEditMedicineRegNo] = useState(""); const [editMedicineType, setEditMedicineType] = useState(""); // 监听medicineStock变化,同步更新编辑状态 useEffect(() => { if (medicineStock) { setEditMedicineName(medicineStock.data.medicineName); setEditMedicineRegNo(medicineStock.data.medicineRegNo); setEditMedicineType(medicineStock.data.medicineType); } }, [medicineStock]) // 依赖项设为medicineStock,数据变化时触发 return ( <div className='editMedicine'> <div className="editMedicine-title">Edit Medicine</div> <form className="editMedicine-form" > <div> <p> <label className="editMedicine-dataTitle">Name: </label> <input name="medicineName" type="text" required className="editMedicine-input" value={editMedicineName} onChange={(e) => setEditMedicineName(e.target.value)} /> </p> <p> <label className="editMedicine-dataTitle">Reg No: </label> <input name="medicineRegNo" type="text" required className="editMedicine-input" value={editMedicineRegNo} onChange={(e) => setEditMedicineRegNo(e.target.value)} /> </p> <p> <label className="editMedicine-dataTitle">Type: </label> <select className="editMedicine-input" value={editMedicineType} onChange={(e) => setEditMedicineType(e.target.value)}> <option value="Tablet">Tablet</option> <option value="Capsule">Capsule</option> <option value="Liquid">Liquid</option> <option value="Spray">Spray</option> <option value="Cream">Cream</option> <option value="Ointment">Ointment</option> </select> </p> </div> </form> </div> ) }
关键改动说明
- 替换
filter为find:因为我们要找单个匹配ID的药品,find直接返回第一个匹配元素,比filter返回数组更贴合场景 - 简化初始状态:编辑状态初始值设为空字符串,不用在初始化时尝试获取还未加载的数据
- 新增同步状态的
useEffect:当medicineStock从undefined变为有数据的对象时,自动把药品信息同步到编辑状态,确保输入框能正确显示初始值 - 符合受控组件规范:用状态单独管理编辑值,后续提交修改时逻辑更清晰,也符合React受控组件的最佳实践
内容的提问来源于stack exchange,提问作者Jacky cky
相关产品推荐
相关产品推荐

