React复选框文本值如何存入Firestore,报indexOf不是函数怎么解决
问题原因及修复方案
核心问题点
- 状态修改不符合React immutable规范:直接对state数组调用
splice、push修改原数组,会导致state更新异常,严重时会把数组类型的state改成非数组,调用indexOf时就会抛出你遇到的类型错误 - 选中逻辑前后不匹配:触发
handleChange时传入的是复选框的文本值,但判断选中状态时用的是复选框的id值,两者完全不匹配,导致选中状态全部错误 - 复选框属性使用错误:checkbox的选中状态属性是
checked,不是selected,你写的selected属性不会生效
修正后代码
import React, { useState } from "react"; const checkboxes = [ { id: 1, text: "Checkbox 1" }, { id: 2, text: "Checkbox 2" }, { id: 3, text: "Checkbox 3" } ]; const SearchResults = () => { // 如果要存id可以自行调整逻辑,示例和你原有需求统一存文本值 const [selectedCheckbox, setSelectedCheckbox] = useState([]); const handleChange = (text) => { let newSelected; if (selectedCheckbox.includes(text)) { // 过滤返回新数组,不修改原state newSelected = selectedCheckbox.filter(item => item !== text); } else { // 拼接返回新数组,不修改原state newSelected = [...selectedCheckbox, text]; } setSelectedCheckbox(newSelected); }; const handleSubmit = async (e) => { e.preventDefault(); console.log(JSON.stringify(selectedCheckbox)); try { const userRef = db.collection("users").doc(uid); // Firestore支持直接写入数组类型 await userRef.set({ selectedCheckbox }); console.log("done") } catch (err) { console.log(err); } }; return ( <div> <div className="App"> <form onSubmit={handleSubmit}> {checkboxes.map((checkbox) => ( <label key={checkbox.id}> {checkbox.text} <input type="checkbox" onChange={() => handleChange(checkbox.text)} // 用正确的checked属性,判断逻辑和传参统一 checked={selectedCheckbox.includes(checkbox.text)} /> </label> ))} <button type="submit">Submit</button> </form> </div> <p>Selected checkboxes: {JSON.stringify(selectedCheckbox)}</p> </div> ); };
改动说明
- 所有状态修改都返回新数组,不直接修改原state,避免更新异常
- 统一选中判断逻辑,传入
handleChange和判断checked都用相同的字段,如果你要存id把两处都改成checkbox.id即可 - 把错误的
selected属性改成checked,正确显示复选框选中状态 - 给
set方法加了await,因为Firestore的set是异步方法,不加await不会正确捕获抛出的异常
内容的提问来源于stack exchange,提问作者JS3
相关产品推荐
相关产品推荐

