React中postList.map is not a function报错问题求助
Firebase查询数据后的状态设置与渲染问题
第一个写法的错误原因
你第一次的代码里,在forEach循环中调用setPostList(...postList, doc.data()),会直接把postList从数组变成单个对象:
- 初始
postList是空数组,第一次执行时,...postList展开后无内容,相当于调用setPostList(doc.data()),直接把状态改成了对象而非数组 - 后续循环再调用时,
postList已经是对象,展开对象会把键值对作为参数传递,彻底破坏数组结构,所以postList.map()会报错“map不是函数”
第二个写法的问题
你第二次的getData写法其实是正确的,已经把查询到的文档转成了包含id和文档数据的数组,但渲染时犯了错误:
在postList.map((doc) => {<Block question={doc.data().item} answer={doc.data().details} />})里,doc已经是你通过posts.docs.map((doc) => ({ id: doc.id, ...doc.data() }))处理过的对象,里面直接包含item和details字段,不需要再调用doc.data()。
正确的完整代码示例
数据获取部分
const [postList, setPostList] = useState([]); const getData = async () => { const q = query(collection(db, "data"), where("title", "==", title)); try { const posts = await getDocs(q); // 将文档数组转成包含id和数据的对象数组 const data = posts.docs.map((doc) => ({ id: doc.id, ...doc.data() })); setPostList(data); } catch (e) { console.log(e.message); } }; // 组件挂载时调用数据获取(示例) useEffect(() => { getData(); }, [title]);
渲染部分
{postList.map((item) => ( <Block key={item.id} // 必须加唯一key,避免React警告 question={item.item} answer={item.details} /> ))}
关键注意点
- 状态更新时一定要确保
postList始终是数组类型,不要直接把单个对象赋值给它 - 处理Firebase文档时,一旦用
...doc.data()展开后,后续直接访问对象属性即可,无需再调用data()方法 - 数组渲染时必须给每个元素加唯一的
key属性(这里用文档的id最合适)
内容的提问来源于stack exchange,提问作者esoteric elf
相关产品推荐
相关产品推荐

