You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 07:06:03