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

React+TypeScript中Firebase异步数据传入表格变量及useState报错问题

React+TS项目Firebase异步数据对接表格组件实现方案

问题描述

在React + TypeScript项目中,需要拉取Firebase实时数据库数据传递给自定义表格组件渲染,初始实现存在两个核心问题:

  • 时序异常:表格初次渲染时机早于Firebase异步数据返回完成,无法渲染拉取到的数组内容
  • 类型报错:尝试使用useState管理表格数据时出现TypeScript类型不匹配问题

初始问题代码如下:

const data = useMemo<DummyDataType[]>(
  () => [
    {
      userId: "Foo",
      flowAmount: "Bar",
    },
  ],
  []
);

const arr: { userId: string; flowAmount: string }[] = [];

var leadsRef = db.ref('users');
leadsRef.on('value', function(snapshot) {
  snapshot.forEach(item => { 
    arr.push({userId: 'test', flowAmount: 'test'})
  })
}); 

const Table = useTable<DummyDataType>({
  columns: columns,
  data: data,
  isDataLoading: false,
  isDataLoadingError: false,
  isRowSelectable: false,
  isMultiRowSelectable: false,
});
return (
  <Box p="4" color="white" bg="rgb(35, 36, 41)">
      <Button colorScheme='yellow' > Save changes</Button>
    {Table}
  </Box>
);

尝试用useState重构数据定义时的错误写法:

type DummyDataType = {
  userId: ReactNode;
  flowAmount: ReactNode;
};
const data = useState<DummyDataType[]>(
  () => [
    {
      userId: "Foo",
      flowAmount: "Bar",
    },
  ],
  []
);

问题根因

  • 异步渲染逻辑错误:Firebase的on('value')是异步监听回调,普通作用域数组arr不会触发组件重渲染,每次组件重渲染时arr都会被重置为空数组,表格无法感知数据更新
  • useState语法错误:useState的返回值是*[状态值, 状态更新函数]*的二元元组,直接将返回值整体传给表格data参数会触发类型错误;同时useState仅接收1个初始化参数,多传的第二个空数组属于无效语法
  • 存在内存泄漏风险:Firebase实时监听未在组件卸载时解绑,会导致重复监听、内存占用异常

正确实现代码

import { useState, useEffect } from 'react';
// 按项目实际依赖引入对应组件
import { Box, Button } from '@chakra-ui/react';

// 类型定义:字段为普通字符串时直接定义为string类型,无需使用ReactNode
type DummyDataType = {
  userId: string;
  flowAmount: string;
};

const DataTablePage = () => {
  // 定义表格数据、加载状态,useState仅传入一个初始值参数
  const [tableData, setTableData] = useState<DummyDataType[]>([
    {
      userId: "Foo",
      flowAmount: "Bar",
    }
  ]);
  const [isDataLoading, setIsDataLoading] = useState<boolean>(true);

  useEffect(() => {
    const leadsRef = db.ref('users');

    // 数据变更回调
    const handleDataSnapshot = (snapshot: any) => {
      const fetchedList: DummyDataType[] = [];
      snapshot.forEach((item: any) => {
        // 替换为实际的Firebase字段取值逻辑
        const itemData = item.val();
        fetchedList.push({
          userId: itemData.userId || '',
          flowAmount: itemData.flowAmount || ''
        })
      });
      // 更新状态触发组件重渲染
      setTableData(fetchedList);
      setIsDataLoading(false);
    };

    // 绑定Firebase实时监听
    leadsRef.on('value', handleDataSnapshot);

    // 组件卸载时解绑监听,避免内存泄漏
    return () => {
      leadsRef.off('value', handleDataSnapshot);
    }
  }, []);

  const Table = useTable<DummyDataType>({
    columns: columns,
    data: tableData,
    isDataLoading: isDataLoading,
    isDataLoadingError: false,
    isRowSelectable: false,
    isMultiRowSelectable: false,
  });

  return (
    <Box p="4" color="white" bg="rgb(35, 36, 41)">
        <Button colorScheme='yellow'>Save changes</Button>
      {Table}
    </Box>
  );
};

export default DataTablePage;

关键修正点

  • 修正useState用法:通过解构获取状态值tableData和更新方法setTableData,仅传入1个初始化参数,从根源解决类型报错
  • 异步逻辑移入useEffect:组件挂载后再绑定Firebase监听,数据返回后通过更新状态触发组件重渲染,解决时序不同步问题
  • 增加真实加载状态:数据拉取过程中表格可展示加载态,避免空数据异常展示
  • 增加监听清理逻辑:组件卸载时移除Firebase监听,避免内存泄漏
  • 优化类型定义:普通文本字段直接定义为string类型,减少不必要的类型兼容问题

内容的提问来源于stack exchange,提问作者like who

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:42:26