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

React类组件转Hook组件的最优方式咨询及useState改造后TypeError报错排查求助

问题:React Data Grid 类组件转Hook后报错及最优转换方案

你遇到的TypeError: Cannot read property 'length' of undefined是因为状态更新后的数据结构出错,同时组件内函数的声明方式也存在问题。我们一步步分析并解决:

错误原因拆解

  1. 函数声明不符合Hook组件规范:在函数组件里,不能用类组件那种onGridRowsUpdated = (...) => {}的赋值写法,必须用const来声明组件内函数。
  2. 状态更新返回值类型错误:你在setRows的回调里返回了{ rows }(一个包含数组的对象),但原本的rows状态是数组类型,这导致React Data Grid后续读取数组length属性时,拿到的却是对象,直接触发报错。
  3. 闭包导致的状态过期问题:直接用外部的rows做slice()操作,可能会捕获到旧的状态值,导致更新结果不准确,应该用函数式更新提供的currentRows参数(当前最新状态)来操作。

修正后的完整代码

import React, { useState } from "react";
import ReactDataGrid from "react-data-grid";
import "./styles.css";

const App = () => {
  // 固定列配置移到组件外部,避免重复创建
  const columns = [
    { key: "id", name: "ID", editable: true },
    { key: "title", name: "Title", editable: true },
    { key: "complete", name: "Complete", editable: true }
  ];

  const [rows, setRows] = useState([
    { id: 0, title: "Task 1", complete: 20 },
    { id: 1, title: "Task 2", complete: 40 },
    { id: 2, title: "Task 3", complete: 60 }
  ]);

  // 正确声明组件内处理函数
  const onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
    setRows((currentRows) => {
      // 基于最新状态创建副本,避免直接修改原数组
      const newRows = [...currentRows];
      for (let i = fromRow; i <= toRow; i++) {
        newRows[i] = { ...newRows[i], ...updated };
      }
      // 返回数组,保持状态结构与初始值一致
      return newRows;
    });
  };

  return (
    <ReactDataGrid
      columns={columns}
      rowGetter={(i) => rows[i]}
      // 动态获取行数,避免固定值导致数据更新后行数不匹配
      rowsCount={rows.length}
      onGridRowsUpdated={onGridRowsUpdated}
      enableCellSelect={true}
      editable={true}
    />
  );
};

export default App;

类组件转Hook的最优实践建议

  1. 保持状态结构一致性:类组件中的state如果是对象/数组,Hook中要严格保持相同的结构,避免更新后类型不匹配引发错误。
  2. 依赖旧状态时用函数式更新:当新状态需要基于旧状态计算时,一定要用setState(prevState => newState)的形式,避免闭包捕获过期状态。
  3. 组件内函数的正确声明:函数组件内的函数必须用const/let声明,不能沿用类组件的赋值写法。
  4. 动态计算依赖属性:比如rowsCount不要写固定数值,改用rows.length,这样数据变化时能自动同步组件配置。
  5. 提取固定配置到组件外部:像columns这种不会变化的配置,移到组件外部可以减少不必要的重复创建,提升渲染性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 06:58:15