React项目查询Firestore数据赋值useState出现类型错误如何解决
问题根因
你遇到的类型报错和状态不更新问题由以下几个错误导致:
- 状态更新函数用法错误:
setId是useState返回的函数,不能直接用setId = xxx赋值,必须通过setId(新状态值)的方式调用,你直接赋值相当于把函数覆盖为数组,自然触发类型不匹配报错。 - 类型不兼容:Firestore返回的
doc.data()默认是DocumentData类型,和你声明的Identification类型不匹配,需要手动做类型断言。 - 状态更新逻辑错误:在
forEach中循环更新状态会导致状态反复覆盖,而且依赖旧person状态时容易触发闭包陷阱,应该先收集所有查询结果再一次性更新状态。 - Hook使用违规:你把
useEffect直接写在了onClick事件回调里,违反了Hook只能在组件顶层调用的规则。
修复后的完整代码
import React, {ChangeEvent} from "react"; import { useState } from "react"; import LongText from "../atoms/LongText"; import AppListBI from "./AppListBI"; import {Identification} from "../../assets/Person/Person"; import db from "../../firebase.config" const Core = () => { const [input, setInput] = useState('') const [showResults, setShowResults] = useState(false) const [person, setId] = useState<Identification[]>([]); const fetchBI = async () => { // 空输入直接跳过查询 if(!input.trim()) return try { const snapshot = await db.collection('id').where('numberId','==',input).get() // 收集所有结果并做类型转换 const searchResult: Identification[] = snapshot.docs.map(doc => doc.data() as Identification) // 一次性更新状态 setId(searchResult) setShowResults(searchResult.length > 0) } catch (err) { console.error('查询失败:', err) } } return ( <> <div className="mx-7"> <span className="font-bold text-xl"><h5>Pesquisar:</h5></span> </div> <div className="flex justify-center"> <LongText placeholder="Pesquisar Id" onChange={(e: ChangeEvent<HTMLInputElement>)=>setInput(e.target.value)} // 直接绑定点击回调,不要在事件里写useEffect onClick={fetchBI} /> </div> <div className="flex justify-center"> <span className="my-4 w-11/12"> { showResults ? <AppListId persons={person} /> : null } </span> </div> </> ); } export default Core;
额外优化建议
- 所有状态声明都用
const不要用var,避免变量被意外覆盖 - 可以加个加载状态,查询过程中展示加载提示提升用户体验
- 如果
Identification的字段和Firestore返回的字段有差异,需要手动做字段映射,不要直接用as断言规避类型检查
内容的提问来源于stack exchange,提问作者Luthermilla Ecole
相关产品推荐
相关产品推荐

