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

React-table接收EventSource新数据后不显示问题求助

问题分析与解决方案

核心问题

  1. State更新违反不可变性原则:直接修改原tableData数组的引用,React无法检测到state变化,因此不会触发表格重渲染。
  2. useEffect闭包陷阱:useEffect依赖数组未包含tableData,导致回调始终捕获初始渲染时的tableData值,每次接收新消息都会覆盖之前的状态。
  3. 列定义类型错误:tableColumns的accessor被定义为never类型,React-table无法通过该字段匹配数据,这是接收消息后表格变空的直接原因。

修复代码

1. 正确更新表格数据(遵循不可变性)

不要直接修改原数组,改用函数式更新创建新数组,确保React能检测到state变化:

eventSource.onmessage = (event) => {
  const newData = JSON.parse(event.data).payload;
  console.log(newData);
  // 基于最新状态创建新数组,添加新数据
  setTableData(prevData => [...prevData, newData]);
};

2. 修正列定义类型

将accessor类型改为实际数据字段的类型(如string),确保与数据结构匹配:

const [tableColumns, setTableColumns] = useState<
  { Header: string; accessor: string }[]
>([]);

// 示例:根据你的数据结构初始化列
useEffect(() => {
  setTableColumns([
    { Header: '通知ID', accessor: 'id' },
    { Header: '通知内容', accessor: 'content' },
    { Header: '创建时间', accessor: 'createTime' }
  ]);
}, []);

3. 优化useEffect逻辑(避免闭包问题)

使用函数式更新后,无需将tableData加入依赖数组,同时确保组件卸载时关闭EventSource:

useEffect(() => {
  const eventSource = new EventSource(SseApiUrl);

  eventSource.onmessage = (event) => {
    const newData = JSON.parse(event.data).payload;
    console.log(newData);
    setTableData(prevData => [...prevData, newData]);
  };

  return () => {
    eventSource.close();
  };
}, [SseApiUrl]);

完整修复后的关键代码片段

const [tableData, setTableData] = useState([]);
// 修正列类型为实际的accessor类型
const [tableColumns, setTableColumns] = useState<
  { Header: string; accessor: string }[]
>([]);

// 初始化列与初始数据(示例)
useEffect(() => {
  // 这里添加从数据库获取初始数据的逻辑
  // setTableData(initialData);
  // 初始化列
  setTableColumns([
    { Header: '通知ID', accessor: 'id' },
    { Header: '通知内容', accessor: 'content' },
    { Header: '创建时间', accessor: 'createTime' }
  ]);
}, []);

useEffect(() => {
  const eventSource = new EventSource(SseApiUrl);

  eventSource.onmessage = (event) => {
    const newData = JSON.parse(event.data).payload;
    console.log(newData);
    setTableData(prevData => [...prevData, newData]);
  };

  return () => {
    eventSource.close();
  };
}, [SseApiUrl]);

const data = useMemo(() => tableData, [tableData]);
const columns = useMemo(() => tableColumns, [tableColumns]);

const tableInstance = useTable({ columns, data });
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = tableInstance;

额外说明

  • 确保从EventSource获取的newData结构与列定义的accessor字段完全匹配,否则React-table无法正确渲染数据。
  • 初始数据库数据的获取逻辑需放在单独的useEffect中,确保组件挂载时先加载基础数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:33:15