Skip to content

Conversation

li-jia-nan
Copy link
Member

@li-jia-nan li-jia-nan commented Sep 14, 2025

Summary by CodeRabbit

  • 新功能

  • 重构

    • 大范围类型与组件声明调整(函数改为 const 箭头、React.FC/PropsWithChildren、refs 初始值改为 null),部分导出签名与组件类型表面发生变化(含 Table/VirtualTable/genTable 等),且将 scroll.y 由必需改为可选。
  • 文档

    • 示例调整与 ESLint 指令移除,示例回调参数用法有小变更。
  • 测试

    • 测试中 ref 初始化改为 null(无行为变化)。
  • 杂务

    • 依赖升级:迁移至 React 19 系列并更新相关类型与测试库,移除重复依赖。

Copy link

vercel bot commented Sep 14, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
table Ready Ready Preview Comment Sep 15, 2025 1:47am

Copy link

coderabbitai bot commented Sep 14, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

本次变更主要为类型与初始化一致性调整:大量将 useRef 初值显式设为 null、细化/放宽 React 元素与 useMemo 泛型、将若干组件改为箭头函数 / React.FC,并升级 package.json 中 React、类型与测试依赖;部分 VirtualTable 将 StaticContext 的 onScroll 串接到虚拟列表。

Changes

Cohort / File(s) Summary
依赖与构建
package.json
升级 react/react-dom^19.1.1,更新 @types/react/@types/react-dom,新增 @rc-component/resize-observer,调整 peerDependencies 为 react/react-dom >=18.0.0,并更新/新增测试相关 devDependencies。
示例与测试(ref/类型细化)
docs/examples/..., tests/Table.spec.jsx
docs/examples/animation.tsx, docs/examples/fixedColumnsAndHeaderRtl.tsx, docs/examples/jsx.tsx, docs/examples/scrollY.tsx, docs/examples/shadow.tsx, docs/examples/stickyHeader.tsx, docs/examples/virtual-list-grid.tsx, docs/examples/virtual-list.tsx, docs/examples/virtual.tsx, tests/Table.spec.jsx
多处将 useRef 初值显式设为 null、细化为 React.ReactElement<any> 或在 useMemo 上指定泛型、移除/恢复 ESLint 指令、微调回调签名(如 onRow),均为类型/初始化或注释级改动,无运行时逻辑变化。
Body / Measure 链路
src/Body/...
src/Body/BodyRow.tsx, src/Body/ExpandedRow.tsx, src/Body/MeasureCell.tsx, src/Body/MeasureRow.tsx, src/Body/index.tsx
添加类型导入并将多处组件从函数声明改为箭头函数/React.FC,expandRowNode 与 cloneElement 的泛型细化,MeasureCell/MeasureRow 在类型层面将 column 相关改为 title,并调整导出/签名形式及 guard 检查。
Footer 相关
src/Footer/...
src/Footer/Row.tsx, src/Footer/Summary.tsx, src/Footer/Cell.tsx, src/Footer/index.tsx
多个 Footer 组件改用 React.FC<React.PropsWithChildren<...>>,接口移除显式 children 并继承/透传标准 HTML 属性,渲染行为保持不变。
Table 与 VirtualTable 核心
src/Table.tsx, src/VirtualTable/...
src/Table.tsx, src/VirtualTable/index.tsx, src/VirtualTable/BodyGrid.tsx, src/VirtualTable/BodyLine.tsx, src/VirtualTable/VirtualCell.tsx
将组件声明改为箭头泛型形式,公开返回类型从 React.ReactElement 改为 React.ReactElement<any>,多处 refs 初值设为 null,TableContextValue 增加 classNames/styles 依赖,默认导出类型扩展以暴露静态字段;BodyGrid 从 StaticContext 提取更多字段并将 onScroll 与虚拟列表对接。
Hooks 与通用严格化
src/hooks/..., src/Cell/index.tsx, src/ColGroup.tsx, src/stickyScrollBar.tsx, src/hooks/useFrame.ts
使用 React.isValidElement<any>、将 useMemo 泛型移动到调用处、计时器句柄改为 `ReturnType
脚本与格式化
script/update-content.js
回调与格式化微调(空格/逗号/括号样式),功能无变更。

Sequence Diagram(s)

sequenceDiagram
  participant StaticContext
  participant BodyGrid
  participant VirtualList
  Note over StaticContext,BodyGrid: 变化:BodyGrid 从 StaticContext 取出 onScroll 并转发
  StaticContext->>BodyGrid: onScroll (aliased as onTablePropScroll)
  BodyGrid->>VirtualList: props.onScroll = onTablePropScroll
  VirtualList->>BodyGrid: scroll events -> onTablePropScroll(event)
  Note right of VirtualList: 事件继续传回 Table 层或上层监听器
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • zombieJ
  • MadCcc

Poem

我是小兔敲代码,ref 归空位更乖巧,
泛型打开迎四海,Measure 只携标题来,
Footer 穿新衣 PropsWithChildren,类型升级到十九代,
虚拟滚动把线牵,onScroll 顺路去传递,
合并分支跳胡萝卜舞,仓库里暖意绕枝梢。 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 该 PR 标题 “update React 16 to React 19” 简洁明确,直接指出此次变更的核心目标。根据变更摘要,主要改动确实是将 package.json 中的 react/react-dom 从 16 升级到 19,并伴随类型定义、示例代码和若干内部 nullability/typing 的调整,标题与这些主要改动高度一致。标题未包含无关信息或模糊措辞,便于团队成员在提交历史中快速识别该合并请求的目的。
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch react-19-update

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @li-jia-nan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on upgrading the project's React dependency to version 19 and enhancing the TypeScript type definitions throughout the codebase. These changes ensure compatibility with the latest React features and improve the overall type safety and maintainability of the components. The update also includes minor refactorings to align with modern React and TypeScript best practices.

Highlights

  • React Version Upgrade: The project has been updated to use React 19.1.1 for development and now declares peer dependencies compatible with React 18.0.0 and above, indicating broader compatibility.
  • TypeScript Type Enhancements: Numerous type definitions have been refined across the codebase, particularly for React.useRef hooks, React.ReactElement instances, and React.isValidElement checks, aligning with stricter TypeScript practices and potentially newer React typing conventions.
  • Ref Initialization with null: Many React.useRef calls are now explicitly initialized with null, a common pattern for ensuring type safety and clarity when working with mutable references in React components.
  • Code Style and Refactoring: Several functional components have been refactored from export default function to const Component: React.FC = ... syntax, and minor simplifications have been made to prop destructuring and object initializations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

socket-security bot commented Sep 14, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​testing-library/​react@​12.1.5 ⏵ 16.3.010010010087100
Updated@​testing-library/​dom@​8.20.1 ⏵ 10.4.19910010088100

View full report

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively updates the project to React 19. The changes are well-executed, primarily addressing compatibility issues such as initializing useRef with null, updating type definitions to align with stricter checks in the new React version, and refactoring some components to modern React.FC syntax. A notable improvement is the enhanced setTimeout and clearTimeout usage in useFrame.ts for better portability. The overall quality of the changes is high. I have one suggestion to improve type safety by avoiding an as any cast when attaching static properties to a component.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/hooks/useFrame.ts (1)

67-71: undefined 统一改为 null,保持类型一致

回调里把 timeoutRef.current 置为 undefined 与声明类型不符,统一置回 null

-    timeoutRef.current = setTimeout(() => {
+    timeoutRef.current = setTimeout(() => {
       frameRef.current = null;
-      timeoutRef.current = undefined;
+      timeoutRef.current = null;
     }, 100);
package.json (1)

5-7: 将 package.json 中的 engines.node 升级为 >=18

vitest@^3、jsdom@26、husky@9 等依赖要求 Node ≥18(已用 npm view 验证)。
位置:package.json 行 5-7

 "engines": {
-  "node": ">=8.x"
+  "node": ">=18"
 }
src/Table.tsx (1)

994-996: 修复 TS2344:CompareProps 约束与 forwardRef 组件不兼容。

CI 报错来自 CompareProps<typeof Table>typeof Table 不是 React.ComponentType。用宽松形参规避约束即可,行为不变。

应用以下最小变更即可消除错误:

-export function genTable(shouldTriggerRender?: CompareProps<typeof Table>) {
+export function genTable(shouldTriggerRender?: CompareProps<any>) {
   return makeImmutable(RefTable, shouldTriggerRender) as ForwardGenericTable;
 }

如需更稳健(在类型层面避免再度回归),也可同时断言入参组件类型:

-  return makeImmutable(RefTable, shouldTriggerRender) as ForwardGenericTable;
+  return makeImmutable(RefTable as unknown as React.ComponentType<any>, shouldTriggerRender) as ForwardGenericTable;

请在本地或 CI 复现验证:

#!/bin/bash
# 1) 仅类型检查
npm run tsc

# 2) 搜索 CompareProps 使用点,确认无其它类似约束
rg -n --type=ts "CompareProps<[^>]+>" -C2

# 3) 快速编译用例(CI 已过):应保持通过
npm test
🧹 Nitpick comments (12)
src/VirtualTable/BodyLine.tsx (1)

42-42: 局部类型放宽 OK,但可更贴合实际语义

expandRowNode 初始为未赋值状态,建议显式标注可为空并初始化为 null,以匹配后续条件赋值与渲染分支。

-  let expandRowNode: React.ReactElement<any>;
+  let expandRowNode: React.ReactElement | null = null;
docs/examples/virtual-list.tsx (1)

36-40: 避免在 ref 尚未赋值时调用实例方法的潜在空引用

useEffect 首次运行时 gridRef.current 可能为 null。建议使用可选链或显式判空以防示例在少数渲染顺序下崩溃。

-  React.useEffect(() => {
-    gridRef.current.resetAfterIndices({ columnIndex: 0, shouldForceUpdate: false });
-  }, []);
+  React.useEffect(() => {
+    gridRef.current?.resetAfterIndices({ columnIndex: 0, shouldForceUpdate: false });
+  }, []);
src/Body/ExpandedRow.tsx (1)

62-62: 将内联样式中的 null 改为 undefined 以匹配类型定义

在 React 的 CSSProperties 中,样式值通常为 string | number | undefined。使用 undefined 更稳妥,避免潜在的类型告警。

-    <Component className={className} style={{ display: expanded ? null : 'none' }}>
+    <Component className={className} style={{ display: expanded ? undefined : 'none' }}>
src/ColGroup.tsx (1)

16-16: 避免在元素类型上使用 any,改用更贴近实际的类型

这里用 React.ReactElement[] 放大了类型范围。更推荐使用 JSX.Element[](或保持 React.ReactElement[] 不加 any)。

-  const cols: React.ReactElement<any>[] = [];
+  const cols: JSX.Element[] = [];
docs/examples/animation.tsx (1)

14-14: nodesRef 的键类型应覆盖 number;cloneElement 泛型使用 LGTM

  • React.Key 可能为 string 或 number,这里 Record 仅用 string 会造成类型不精确。
  • cloneElement 的显式泛型用于宽化 props 合理。
-  const nodesRef = React.useRef<Record<string, React.ReactElement<any>>>({});
+  const nodesRef = React.useRef<Record<string | number, React.ReactElement<any>>>({});

Also applies to: 29-31

docs/examples/virtual-list-grid.tsx (1)

26-26: ref 初始为 null 时,effect 内应加可选链保护

首次渲染后 ref 可能尚未赋值(尤其在严格模式/并发下)。加上可选链更稳妥。

   React.useEffect(() => {
-    gridRef.current.resetAfterIndices({
+    gridRef.current?.resetAfterIndices({
       columnIndex: 0,
       shouldForceUpdate: false,
     });
   }, []);

Also applies to: 47-51

src/hooks/useColumns/index.tsx (1)

241-241: 保留 eslint 禁用 OK,但建议补注释原因

这里禁用 exhaustive-deps 是出于稳定性考虑(避免 transformColumns 频繁变更触发),建议加一句注释说明原因,方便后续维护者。

docs/examples/scrollY.tsx (1)

97-97: 文档可读性小建议:保留形参占位以提示签名

onRow 去掉形参类型上没问题;为提升读者对签名 (record, index) 的认知,可用占位符保留参数。

可选 diff:

-        onRow={() => ({ style: { backgroundColor: 'red' } })}
+        onRow={(_record, _index) => ({ style: { backgroundColor: 'red' } })}
src/Body/MeasureCell.tsx (1)

16-21: 副作用依赖的稳健性检查

当前 useLayoutEffect 依赖为空,仅在首次挂载量测。如果父层可能在运行期更换 onColumnResizecolumnKey,会出现闭包陈旧问题。若上层保证二者稳定则可保持;否则建议纳入依赖或用稳定回调封装。

可选 diff:

-  useLayoutEffect(() => {
+  useLayoutEffect(() => {
     if (cellRef.current) {
       onColumnResize(columnKey, cellRef.current.offsetWidth);
     }
-  }, []);
+  }, [onColumnResize, columnKey]);
src/Table.tsx (1)

984-987: ForwardGenericTable 返回类型改为 ReactElement。建议去除 any。

保持 React.ReactElement 或使用 JSX.Element 可避免不必要的 any 外泄。

可选微调:

-export type ForwardGenericTable = (<RecordType extends DefaultRecordType = any>(
-  props: TableProps<RecordType> & React.RefAttributes<Reference>,
-) => React.ReactElement<any>) & { displayName?: string };
+export type ForwardGenericTable = (<RecordType extends DefaultRecordType = any>(
+  props: TableProps<RecordType> & React.RefAttributes<Reference>,
+) => React.ReactElement) & { displayName?: string };
package.json (1)

87-91: React/ReactDOM 升级至 ^19.1.1,LGTM。

与 peer 要求(≥18)兼容。若期望限制到 <20,可追加上限以减少未知主版本风险。

可选:

-  "peerDependencies": {
-    "react": ">=18.0.0",
-    "react-dom": ">=18.0.0"
-  },
+  "peerDependencies": {
+    "react": ">=18.0.0 <20",
+    "react-dom": ">=18.0.0 <20"
+  },
src/Body/BodyRow.tsx (1)

228-229: expandRowNode 需允许为空以避免“未赋值使用”的隐患。

当前声明为非空 ReactElement<ExpandedRowProps>,在未满足展开条件时将保持 undefined。建议显式使用 null 初值并扩大联合类型。

应用修正:

-  let expandRowNode: React.ReactElement<ExpandedRowProps>;
+  let expandRowNode: React.ReactElement<ExpandedRowProps> | null = null;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49f26c0 and d3af8c6.

📒 Files selected for processing (30)
  • docs/examples/animation.tsx (2 hunks)
  • docs/examples/fixedColumnsAndHeaderRtl.tsx (1 hunks)
  • docs/examples/jsx.tsx (0 hunks)
  • docs/examples/scrollY.tsx (2 hunks)
  • docs/examples/shadow.tsx (0 hunks)
  • docs/examples/stickyHeader.tsx (1 hunks)
  • docs/examples/virtual-list-grid.tsx (1 hunks)
  • docs/examples/virtual-list.tsx (1 hunks)
  • docs/examples/virtual.tsx (1 hunks)
  • package.json (4 hunks)
  • src/Body/BodyRow.tsx (2 hunks)
  • src/Body/ExpandedRow.tsx (1 hunks)
  • src/Body/MeasureCell.tsx (2 hunks)
  • src/Body/MeasureRow.tsx (2 hunks)
  • src/Body/index.tsx (1 hunks)
  • src/Cell/index.tsx (2 hunks)
  • src/ColGroup.tsx (1 hunks)
  • src/FixedHolder/index.tsx (1 hunks)
  • src/Footer/Row.tsx (1 hunks)
  • src/Footer/Summary.tsx (1 hunks)
  • src/Table.tsx (5 hunks)
  • src/VirtualTable/BodyGrid.tsx (3 hunks)
  • src/VirtualTable/BodyLine.tsx (1 hunks)
  • src/VirtualTable/index.tsx (1 hunks)
  • src/hooks/useColumns/index.tsx (1 hunks)
  • src/hooks/useFlattenRecords.ts (1 hunks)
  • src/hooks/useFrame.ts (1 hunks)
  • src/hooks/useStickyOffsets.ts (1 hunks)
  • src/stickyScrollBar.tsx (1 hunks)
  • tests/Table.spec.jsx (1 hunks)
💤 Files with no reviewable changes (2)
  • docs/examples/shadow.tsx
  • docs/examples/jsx.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: bbb169
PR: react-component/table#1202
File: src/Table.tsx:903-904
Timestamp: 2024-11-08T12:53:09.293Z
Learning: 在 `src/Table.tsx` 文件的 React 组件 `Table` 中,即使 `bodyScrollLeft` 频繁更新,也需要在 `TableContextValue` 的 `useMemo` 依赖数组中包含 `bodyScrollLeft` 和 `headerCellRefs`,因为每次滚动时重新计算 `TableContextValue` 是解决该问题所必须的。
📚 Learning: 2024-11-08T12:53:09.293Z
Learnt from: bbb169
PR: react-component/table#1202
File: src/Table.tsx:903-904
Timestamp: 2024-11-08T12:53:09.293Z
Learning: 在 `src/Table.tsx` 文件的 React 组件 `Table` 中,即使 `bodyScrollLeft` 频繁更新,也需要在 `TableContextValue` 的 `useMemo` 依赖数组中包含 `bodyScrollLeft` 和 `headerCellRefs`,因为每次滚动时重新计算 `TableContextValue` 是解决该问题所必须的。

Applied to files:

  • docs/examples/fixedColumnsAndHeaderRtl.tsx
  • src/FixedHolder/index.tsx
  • docs/examples/virtual.tsx
  • src/VirtualTable/BodyGrid.tsx
  • src/stickyScrollBar.tsx
  • docs/examples/scrollY.tsx
  • src/Table.tsx
🧬 Code graph analysis (8)
src/Body/BodyRow.tsx (1)
src/Body/ExpandedRow.tsx (1)
  • ExpandedRowProps (8-18)
docs/examples/fixedColumnsAndHeaderRtl.tsx (1)
tests/FixedColumn-IE.spec.jsx (1)
  • columns (27-40)
src/hooks/useStickyOffsets.ts (1)
src/interface.ts (1)
  • StickyOffsets (143-148)
docs/examples/virtual.tsx (2)
src/interface.ts (1)
  • Reference (48-51)
src/index.ts (1)
  • Reference (24-24)
src/stickyScrollBar.tsx (1)
src/hooks/useFrame.ts (1)
  • useLayoutState (8-50)
src/Body/index.tsx (1)
src/context/PerfContext.tsx (1)
  • PerfRecord (3-5)
docs/examples/scrollY.tsx (1)
src/interface.ts (1)
  • Reference (48-51)
src/Footer/Summary.tsx (1)
src/index.ts (1)
  • Summary (14-14)
🪛 GitHub Actions: ✅ test
src/Cell/index.tsx

[error] Property 'children' does not exist on type 'unknown'.

src/Table.tsx

[error] TS2344: Type '(tableProps: TableProps, ref: Ref) => Element' does not satisfy the constraint 'ComponentType'.

src/hooks/useColumns/index.tsx

[error] Property 'children' does not exist on type '{}'. Rest types may only be created from object types.

🔇 Additional comments (28)
src/FixedHolder/index.tsx (1)

78-78: 纯格式化变更,OK

仅插入空行,无行为差异。

tests/Table.spec.jsx (1)

1237-1237: 将 ref 初始值改为 null 与源码一致,OK

与生产代码的空值语义对齐,避免 undefined/null 差异。

src/hooks/useStickyOffsets.ts (1)

11-11: useMemo 泛型标注迁移,OK

类型更简洁明了,行为不变。

src/hooks/useFlattenRecords.ts (1)

65-65: useMemo 显式泛型,OK;注意 expandedKeys 的引用稳定性

实现无行为变化。但若上游对同一个 Set 做就地增删而不替换引用,memo 不会重新计算。请确认调用方在 keys 变化时创建新 Set

docs/examples/virtual.tsx (1)

193-193: ref 显式为可空 Reference,OK

与后续使用的可选链匹配,类型与语义一致。

src/stickyScrollBar.tsx (1)

33-33: useRef(null) 的空初始化一致性改动 LGTM

与本 PR 在各处统一的 ref 空初始化策略保持一致,无行为变化。

Also applies to: 41-41

src/VirtualTable/BodyGrid.tsx (1)

53-53: 空初始化与元素泛型宽化 LGTM

  • listRef 使用 useRef(null) 与全局策略一致。
  • extraRender 返回元素类型宽化为 React.ReactElement 与本 PR 其它处一致。若后续需要收紧类型,可再聚焦具体节点 props。

Also applies to: 192-193

docs/examples/fixedColumnsAndHeaderRtl.tsx (1)

40-40: 在 useMemo 处标注泛型而非变量类型,改动合理

不影响运行时,仅为类型书写风格优化,保持一致性即可。

src/Cell/index.tsx (1)

253-259: 为 mergedStyle 补充 CSSProperties 注解 LGTM

类型更明确,有助于防止样式对象误用。

src/hooks/useColumns/index.tsx (1)

140-145: 依赖项合理,保持即可

baseColumnsuseMemo 依赖包含 columnschildren,与转换逻辑一致,无需调整。

docs/examples/scrollY.tsx (1)

16-16: Ref 初始化改为 null 与类型一致,赞

Reference | null 的签名一致,避免初值非空断言,示例更安全。

src/VirtualTable/index.tsx (1)

97-100: 返回类型放宽为 React.ReactElement<any> 合理

与项目内其它 forward 组件保持一致;无行为变更。

src/Body/MeasureRow.tsx (3)

16-22: 迁移为 React.FC 与上下文读取简洁明了

组件形态与项目其余文件一致,可读性更好。


52-53: measureRowRender 做函数性检查更稳妥

由真值判断改为 typeof === 'function',可避免误把非函数子节点当渲染器调用。


40-45: 已确认:MeasureCell 已切换为传 title,且仅在一处被调用

仓库中仅在 src/Body/MeasureRow.tsx 发现 MeasureCell 调用,且已使用 title={column?.title},无需其它改动。

src/Body/MeasureCell.tsx (2)

8-9: Props 从 column 精简为 title,减少耦合

量测仅需标题文本,此变更降低了组件依赖面,方向正确。


11-15: useRef(null) 初始化与 DOM 引用规范一致

避免未定义引用带来的 TS 非空断言。

src/Table.tsx (6)

336-338: 列上下文 useMemo 改写仅为格式调整,语义保持不变,LGTM。


341-344: Ref 初值改为 null 与 React 18/19 的严格空值更一致,LGTM。


382-382: scrollSummaryRef 空值初始化对齐其余滚动节点,LGTM。


397-401: stickyRef 的 null 初始值与可选链访问配合合理。


637-647: emptyNode 的 useMemo 明确了泛型,避免推断抖动,LGTM。


867-979: 确认 TableContext useMemo 的滚动相关依赖(需人工核实)

在仓库中用 rg -n "bodyScrollLeft|headerCellRefs" -C2 搜索未返回结果,无法确认这些字段是否存在或已合并为 scrollInfo。在 src/Table.tsx(约 867–979 行)或维护滚动状态的模块中核实:如果存在 bodyScrollLeft 或 headerCellRefs,则把它们加入 TableContext 的 useMemo 依赖数组;若已合并为 scrollInfo,则可忽略本提醒。

package.json (3)

53-53: 新增 @rc-component/resize-observer 依赖对齐源码使用,LGTM。


64-66: @types/react 升级到 19,LGTM。*


99-102: peerDependencies 放宽到 >=18 符合迁移策略,LGTM。

src/Body/BodyRow.tsx (1)

9-9: 类型仅导入 ExpandedRowProps,拆分清晰,LGTM。

src/Body/index.tsx (1)

67-67: perfRef 初始化合并为一行,无行为变更,LGTM。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/Footer/Summary.tsx (1)

12-18: 返回类型不匹配,可能导致 TS 编译报错

React.FC 要求返回 ReactElement | null,当前直接 return children(类型为 ReactNode)在严格模式下会报错。建议显式断言为 React.ReactElement

-} = props => {
-  const { children } = props;
-  return children;
-};
+} = props => {
+  const { children } = props;
+  return children as React.ReactElement;
+};

补充建议(可选):既然使用了 React.FC,可以去掉多余的 PropsWithChildren 注解,或统一全仓库的写法以减少类型噪音。

🧹 Nitpick comments (2)
src/Footer/Cell.tsx (1)

17-19: 可读性与渲染细节小优化

  • React.FC 已自带 children,与 PropsWithChildren 同时使用有点冗余;为与仓库其余处保持一致,可简化为 React.FC<SummaryCellProps>
  • render={() => children} 每次渲染都会新建函数;若 Cellrender 做引用比较,可能造成不必要重渲染。可用 useCallback 稳定引用。

[建议改动]

-const SummaryCell: React.FC<React.PropsWithChildren<SummaryCellProps>> = props => {
-  const { className, index, children, colSpan = 1, rowSpan, align } = props;
+const SummaryCell: React.FC<SummaryCellProps & React.PropsWithChildren> = props => {
+  const { className, index, children, colSpan = 1, rowSpan, align } = props;
+  const render = React.useCallback(() => children, [children]);-      render={() => children}
+      render={render}
src/Table.tsx (1)

986-989: 返回类型中的 any 建议收紧

ForwardGenericTable 的返回值标注为 React.ReactElement<any> 会放宽元素类型信息。建议用 React.ReactElement(或更严格的 React.ReactElement | null)以避免不必要的 any 扩散。

-export type ForwardGenericTable = (<RecordType extends DefaultRecordType = any>(
-  props: TableProps<RecordType> & React.RefAttributes<Reference>,
-) => React.ReactElement<any>) & { displayName?: string };
+export type ForwardGenericTable = (<RecordType extends DefaultRecordType = any>(
+  props: TableProps<RecordType> & React.RefAttributes<Reference>,
+) => React.ReactElement) & { displayName?: string };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3af8c6 and 0b8b9db.

📒 Files selected for processing (3)
  • src/Footer/Cell.tsx (2 hunks)
  • src/Footer/Summary.tsx (1 hunks)
  • src/Table.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-08T12:53:09.293Z
Learnt from: bbb169
PR: react-component/table#1202
File: src/Table.tsx:903-904
Timestamp: 2024-11-08T12:53:09.293Z
Learning: 在 `src/Table.tsx` 文件的 React 组件 `Table` 中,即使 `bodyScrollLeft` 频繁更新,也需要在 `TableContextValue` 的 `useMemo` 依赖数组中包含 `bodyScrollLeft` 和 `headerCellRefs`,因为每次滚动时重新计算 `TableContextValue` 是解决该问题所必须的。

Applied to files:

  • src/Table.tsx
🧬 Code graph analysis (2)
src/Table.tsx (2)
src/interface.ts (2)
  • DefaultRecordType (28-28)
  • Reference (48-51)
src/context/TableContext.tsx (1)
  • makeImmutable (21-21)
src/Footer/Summary.tsx (1)
src/index.ts (1)
  • Summary (14-14)
🔇 Additional comments (10)
src/Footer/Cell.tsx (1)

44-46: 默认导出保持一致,LGTM

与 Footer 其余子组件的导出方式一致,便于按需引入与命名空间绑定。

src/Table.tsx (9)

194-198: forwardRef 泛型重构 LGTM

Table 改为泛型箭头并配合 forwardRef 更利于类型推断与 d.ts 生成。


336-337: 列上下文 useMemo 精简 LGTM

简化为对象字面量返回,依赖数组完整。


341-344: Ref 初值设为 null 符合 React 18/19 类型约束

避免非空断言与潜在 NPE,改动合理。


382-382: 为 Summary 区域添加同步滚动 Ref,LGTM

后续在 onInternalScroll 中同步滚动,行为一致。


397-401: stickyRef 显式类型 + null 初值 LGTM

可选调用与存在性检查已覆盖。


637-647: emptyNode 的显式泛型标注 LGTM

更清晰的返回类型,有助于下游消费。


930-932: 将 classNames/styles 纳入 TableContext 依赖,LGTM

这解决了样式/类名热更新不生效的问题,符合先前经验总结。


996-997: genTable 的 CompareProps 目标类型更新 LGTM

ForwardGenericTable 对齐,更准确。


1001-1001: 生成 ImmutableTable 的时机 LGTM

保持工厂封装,静态成员随后挂载。
已验证:src/Footer/index.tsx 第 47 行存在 export const FooterComponents = Summary;,FooterComponents 为值导出。
仍需确认 FooterComponents 是否已被复用/挂载为 ImmutableTable.Summary —— 在仓库根目录运行以下命令并粘贴输出以便最终确认:

rg -nP --glob 'src/**' 'ImmutableTable\s*\.\s*Summary|\.Summary\s*=' -n -C3 || true
fd -a --glob 'src/index.*' | xargs -I{} rg -n 'export.*Summary' {} || true

Copy link

codecov bot commented Sep 14, 2025

Codecov Report

❌ Patch coverage is 96.89922% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.11%. Comparing base (49f26c0) to head (d286d53).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
script/update-content.js 0.00% 4 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1355   +/-   ##
=======================================
  Coverage   96.11%   96.11%           
=======================================
  Files          57       57           
  Lines        3447     3449    +2     
  Branches      630      632    +2     
=======================================
+ Hits         3313     3315    +2     
  Misses        129      129           
  Partials        5        5           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

5-7: 修正 engines:当前依赖链已要求 Node ≥ 18

本包仍声明 "node": ">=8.x",与实际依赖不符,可能导致 CI/用户环境误配:

  • Vitest 需 Node ≥ 18,官方文档明确要求。 (vitest.dev)
  • Husky v9 的 enginesnode: ">=18"。 (app.unpkg.com)
  • jsdom 26.x 要求 Node ≥ 18(GitHub README 近期甚至标注 ≥ 20)。 (npmjs.com)

建议更新为 Node 18+(或更保守地 18.18+):

   "engines": {
-    "node": ">=8.x"
+    "node": ">=18"
   },
♻️ Duplicate comments (2)
src/hooks/useColumns/index.tsx (1)

23-25: 用类型谓词收窄 ReactNode → ReactElement,移除 as any 断言

当前 .filter(node => React.isValidElement<any>(node)) 只是返回 boolean,TS 不会把结果数组收窄成 ReactElement[],于是后续 .map 中不得不使用 as React.ReactElement<any> 进行断言,掩盖潜在类型问题。建议使用类型谓词的写法完成收窄,并直接使用已收窄的 node,无需断言;这也与之前的建议一致。

可直接应用以下 diff:

-  return toArray(children)
-    .filter(node => React.isValidElement<any>(node))
-    .map(node => {
-      const { key, props } = node as React.ReactElement<any>;
+  return toArray(children)
+    .filter(
+      (node): node is React.ReactElement<React.PropsWithChildren<any>> =>
+        React.isValidElement(node),
+    )
+    .map(node => {
+      const { key, props } = node;
       const { children: nodeChildren, ...restProps } = props;

为稳妥起见,请在本文件与相邻模块统一采用上述类型谓词写法,避免 as any

#!/bin/bash
# 检查本仓库仍存在的 ReactElement any 断言与非谓词式 isValidElement 用法
rg -nP 'as\s+React\.ReactElement<any>' -g '!**/dist/**'
rg -nP 'filter\([^)]*=>\s*React\.isValidElement<*' --type ts --type tsx -g '!**/dist/**'

Also applies to: 26-26

src/Footer/Row.tsx (1)

3-3: 已按此前建议放宽 <tr> 可透传的原生属性,👍

FooterRowProps 继承 React.HTMLAttributes<HTMLTableRowElement> 符合组合性预期,便于使用者透传事件与 ARIA。

🧹 Nitpick comments (2)
src/Footer/Row.tsx (2)

4-5: 去重:无需再次声明 className/style

两者已由 React.HTMLAttributes<HTMLTableRowElement> 提供,重复声明仅增加噪音。建议精简为“空扩展接口”。

-export interface FooterRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
-  className?: string;
-  style?: React.CSSProperties;
-}
+export interface FooterRowProps extends React.HTMLAttributes<HTMLTableRowElement> {}

8-11: 可选:支持 ref 透传到 <tr>

很多表格场景(测量尺寸、焦点控制)需要拿到行元素的 DOM 引用。可用 forwardRef 轻量支持,保持完全兼容。

-const FooterRow: React.FC<React.PropsWithChildren<FooterRowProps>> = props => {
-  const { children, ...restProps } = props;
-  return <tr {...restProps}>{children}</tr>;
-};
+const FooterRow = React.forwardRef<HTMLTableRowElement, React.PropsWithChildren<FooterRowProps>>(
+  ({ children, ...restProps }, ref) => <tr ref={ref} {...restProps}>{children}</tr>,
+);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b8b9db and b0c465b.

📒 Files selected for processing (4)
  • package.json (3 hunks)
  • src/Cell/index.tsx (2 hunks)
  • src/Footer/Row.tsx (1 hunks)
  • src/hooks/useColumns/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Cell/index.tsx
🔇 Additional comments (4)
src/Footer/Row.tsx (2)

8-11: FC 搭配 PropsWithChildren 用法正确

自 React 18 起,React.FC 不再隐式包含 children,显式包上 PropsWithChildren 的写法更稳妥。

参考:TypeScript 5.1 + React 18 对 FC 的更新说明(不再隐式注入 children)。 (totaltypescript.com)


13-13: 默认导出保持不变,命名清晰

无需改动。

package.json (2)

61-67: 测试与类型依赖升级到 React 19 生态,方向正确

  • 升级 @testing-library/react 至 ^16 并补充 @testing-library/dom,与 React 18/19 升级路径一致。 (newreleases.io)
  • 升级 @types/react/@types/react-dom 与运行时 React 版本对齐。

请在 CI 中同时验证 React 18 与 19 两条 peer 兼容矩阵,确保 RTL v16 在 React 18 下也能通过(历史上 16.1.0 对 React 18 有过个别问题)。 (github.com)

Also applies to: 88-92


53-57: 依赖新增 @rc-component/resize-observer

与表格尺寸监听相关,合理。请确认该依赖对 React 18/19 的 peer 要求与本包一致。

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
package.json (1)

5-7: engines.node 过低且与工具链不符(建议至少 Node 18)

现为 ">=8.x",与 vitest@3、TypeScript 5.9 等现代工具要求不匹配,可能误导用户或导致安装后构建失败。

建议提高到实际最低支持版本(示例):

-  "engines": {
-    "node": ">=8.x"
-  },
+  "engines": {
+    "node": ">=18.18.0"
+  },

并在 README/发布说明同步最低 Node 版本。

♻️ Duplicate comments (2)
package.json (1)

101-104: 这是对 React 16/17 的破坏性变更:请提升主版本或扩大 peer 范围

将 peer 提到 >=18 会使使用 React 16/17 的消费者安装失败,按 semver 应视为 Breaking。

两种可选路径:

  • 路径 A(推荐):确认放弃 <18,提升包主版本并在变更日志中明确。
  • 路径 B:若仍需兼容旧版,临时放宽 peer 范围并在 README 标注 19 为推荐目标,同时在 CI 覆盖旧版。

建议修改(路径 A):

-  "version": "1.7.0",
+  "version": "2.0.0",

如选路径 B,示例(请按真实支持范围调整):

-  "peerDependencies": {
-    "react": ">=18.0.0",
-    "react-dom": ">=18.0.0"
-  },
+  "peerDependencies": {
+    "react": ">=16.9.0",
+    "react-dom": ">=16.9.0"
+  },

并在 CI 增加 React 16/17/18/19 的最小-最大版本采样。

src/Cell/index.tsx (1)

71-76: 移除 any,遵循 React 19 的 isValidElement 断言方式

避免 (children.props as any),改为先判定后显式断言元素 props,增强类型安全。

-    } else if (
-      React.isValidElement<any>(children) &&
-      typeof (children.props as any)?.children === 'string'
-    ) {
-      title = (children.props as any)?.children;
-    }
+    } else if (React.isValidElement(children)) {
+      const el = children as React.ReactElement<{ children?: React.ReactNode }>;
+      if (typeof el.props.children === 'string') {
+        title = el.props.children;
+      }
+    }
🧹 Nitpick comments (10)
package.json (1)

63-63: @testing-library/react 升至 16:确认与 React 19/act 行为一致

请确保测试中使用的 act、flush 微任务相关断言已按 v16 约定更新;CI 覆盖 React 18/19 两个矩阵更稳妥。

script/update-content.js (1)

21-28: 确认:fs.writeFile 回调的尾随逗号与日志级别建议

  • package.json engines 指定 ">=8.x",Node 8+ 支持函数调用/参数的尾随逗号(无运行时兼容性问题)。
  • 仓库未找到显式的 trailingComma / comma-dangle 覆盖(先前的快速搜索受忽略规则影响);但即便无配置,Node 8 已可接受该语法。
  • 仍建议将错误分支改为 console.error 并直接 return(返回 false 无语义效果),并可任选地移除尾随逗号以避免与旧工具链/风格规则冲突。

可接受的最小改动(推荐):

-    function (error) {
-      if (error) {
-        console.log(error);
-        return false;
-      }
-      console.log(`${name} 更新成功~`);
-    },
+    function (error) {
+      if (error) {
+        console.error(error);
+        return;
+      }
+      console.log(`${name} 更新成功~`);
+    }
src/VirtualTable/VirtualCell.tsx (1)

75-86: 防 NaN:仅在列宽为数值时计算 marginOffset

colWidth 可能为字符串(如百分比)。当前 (colWidth as number) - concatColWidth 在运行时不会转换类型,遇到字符串会得到 NaN,导致样式异常。建议加类型守卫。

-  const marginOffset = colSpan > 1 ? (colWidth as number) - concatColWidth : 0;
+  const marginOffset =
+    colSpan > 1 && typeof colWidth === 'number' ? colWidth - concatColWidth : 0;
src/Cell/index.tsx (1)

151-170: 避免布尔算术与潜在 NaN,改为显式偏移计算

(isFixStart && fixedStartShadow && absScroll) - (offsetFixedStartShadow as number) 依赖布尔到数值的隐式转换,且当 offsetFixedStartShadowundefined 时会产生 NaN。建议显式处理:

-    const showStartShadow =
-      (isFixStart && fixedStartShadow && absScroll) -
-        // For precision, we not show shadow by default which has better user experience.
-        (offsetFixedStartShadow as number) >=
-      1;
-    const showEndShadow =
-      (isFixEnd && fixedEndShadow && scrollWidth - absScroll) -
-        // Same as above
-        (offsetFixedEndShadow as number) >=
-      1;
+    const startOffset = offsetFixedStartShadow ?? 0;
+    const endOffset = offsetFixedEndShadow ?? 0;
+    const showStartShadow =
+      (isFixStart && fixedStartShadow ? absScroll : 0) - startOffset >= 1;
+    const showEndShadow =
+      (isFixEnd && fixedEndShadow ? scrollWidth - absScroll : 0) - endOffset >= 1;
src/Panel/index.tsx (1)

3-11: 类型精简:去除重复与不必要包装

  • React.HTMLAttributes<HTMLDivElement> 已包含 classNamestyle,可去重。
  • React.FC 已自带 children,无需 PropsWithChildren
-export interface TitleProps extends React.HTMLAttributes<HTMLDivElement> {
-  className?: string;
-  style?: React.CSSProperties;
-}
+export interface TitleProps extends React.HTMLAttributes<HTMLDivElement> {}
 
-const Panel: React.FC<React.PropsWithChildren<TitleProps>> = props => {
+const Panel: React.FC<TitleProps> = props => {
   const { children, ...restProps } = props;
   return <div {...restProps}>{children}</div>;
 };
src/Body/BodyRow.tsx (1)

160-162: 去重:重复调用 devRenderTimes(props)

上方已调用一次,这里可删除以避免噪音。

-  if (process.env.NODE_ENV !== 'production') {
-    devRenderTimes(props);
-  }
src/Table.tsx (4)

350-356: SSR/多环境健壮性:直接使用 instanceof HTMLElement 可能在无 DOM 环境报错

在 Node/SSR 环境中 HTMLElement 未定义,惰性执行时仍可能触发引用错误。建议加 typeof 守卫。

-        if (scrollBodyRef.current instanceof HTMLElement) {
+        if (typeof HTMLElement !== 'undefined' && scrollBodyRef.current instanceof HTMLElement) {

569-575: 同上:instanceof Element 在 SSR 环境需加守卫

避免 Element 未定义时报错。

-      if (scrollBodyRef.current instanceof Element) {
+      if (typeof Element !== 'undefined' && scrollBodyRef.current instanceof Element) {
         setScrollbarSize(getTargetScrollBarSize(scrollBodyRef.current).width);
       } else {

779-786: 避免对象展开时对 undefined 进行展开导致运行时异常

fixHeaderhorizonScroll 都为假时,scrollXStyle/scrollYStyle 未赋值,直接展开 ...undefined 在原生展开语法下会抛错。建议提供空对象回退。
[建议是稳健性优化,不阻塞合并]

-        style={{
-          ...scrollXStyle,
-          ...scrollYStyle,
-          ...styles?.content,
-        }}
+        style={{
+          ...(scrollXStyle || {}),
+          ...(scrollYStyle || {}),
+          ...(styles?.content || {}),
+        }}

988-988: ForwardGenericTable 返回类型使用 React.ReactElement

可接受,但会略微放宽约束。若希望更窄,考虑 JSX.ElementReact.ReactElement。当前改动不阻塞。

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0c465b and ac85032.

📒 Files selected for processing (14)
  • package.json (3 hunks)
  • script/update-content.js (1 hunks)
  • src/Body/BodyRow.tsx (4 hunks)
  • src/Body/ExpandedRow.tsx (2 hunks)
  • src/Body/index.tsx (4 hunks)
  • src/Cell/index.tsx (3 hunks)
  • src/ColGroup.tsx (2 hunks)
  • src/Footer/index.tsx (2 hunks)
  • src/Panel/index.tsx (1 hunks)
  • src/Table.tsx (7 hunks)
  • src/VirtualTable/BodyGrid.tsx (4 hunks)
  • src/VirtualTable/VirtualCell.tsx (2 hunks)
  • src/VirtualTable/index.tsx (2 hunks)
  • src/stickyScrollBar.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/Body/ExpandedRow.tsx
  • src/stickyScrollBar.tsx
  • src/ColGroup.tsx
  • src/VirtualTable/BodyGrid.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-08T12:53:09.293Z
Learnt from: bbb169
PR: react-component/table#1202
File: src/Table.tsx:903-904
Timestamp: 2024-11-08T12:53:09.293Z
Learning: 在 `src/Table.tsx` 文件的 React 组件 `Table` 中,即使 `bodyScrollLeft` 频繁更新,也需要在 `TableContextValue` 的 `useMemo` 依赖数组中包含 `bodyScrollLeft` 和 `headerCellRefs`,因为每次滚动时重新计算 `TableContextValue` 是解决该问题所必须的。

Applied to files:

  • src/VirtualTable/index.tsx
  • src/Table.tsx
🧬 Code graph analysis (4)
src/Body/BodyRow.tsx (1)
src/Body/ExpandedRow.tsx (1)
  • ExpandedRowProps (8-18)
src/VirtualTable/index.tsx (2)
src/interface.ts (1)
  • Reference (48-51)
src/Table.tsx (1)
  • TableProps (91-188)
src/Table.tsx (1)
src/interface.ts (2)
  • DefaultRecordType (28-28)
  • Reference (48-51)
src/Body/index.tsx (1)
src/context/PerfContext.tsx (1)
  • PerfRecord (3-5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: test / react component workflow
  • GitHub Check: test / react component workflow
🔇 Additional comments (14)
package.json (4)

61-61: Testing Library 升级到 @testing-library/dom@^10:请回归关键交互测试

RTL DOM 10 对部分查询与事件模拟有行为细节变更;建议回归测试,重点覆盖可达性查询与异步断言。


89-92: devDependencies 固定到 React 19.1:建议在 CI 同时验证 React 18 与 19

peer 仅声明 ">=18.0.0",而本地开发依赖锁到 19.1。为确保对 18/19 都稳定,建议在 CI 增加 React 18.x 与 19.x 的测试矩阵。
[offer_operitional_advice]


53-53: 确认新增依赖定位与多版本冲突风险(@rc-component/resize-observer)

package.json(行 53)新增 "@rc-component/resize-observer": "^1.0.0"。已执行 npm 验证:npm ls @rc-component/resize-observer 返回 (empty),当前 npm 依赖树未发现其它实例。仓库出现 "shamefully-hoist" 提示,可能使用 pnpm/monorepo 配置——需在实际包管理器和打包产物下补充核实,建议执行:

pnpm ls @rc-component/resize-observer || true
npm ls @rc-component/resize-observer || true
rg -n "@rc-component/resize-observer" pnpm-lock.yaml package-lock.json yarn.lock || true
# 若有构建产物:rg -n "@rc-component/resize-observer" dist build || true

若该依赖仅为宿主对齐且需共享版本,改为 peerDependencies 并在文档中说明安装指引。


65-67: 无法完成“React 19 类型来源一致性”验证 — 先修复缺失依赖并重跑类型检查

npm run tsc 报大量 "Cannot find module" 与其它 TS 错误,阻止判断 @types/react / @types/react-dom 是否存在重复或版本错配。操作:先安装/修复依赖或在 tsconfig.json 中临时排除 docs/tests,然后重跑类型检查(例如:npm ci && npm run tsc)。若在依赖完整时仍有重复声明告警,移除不必要的 @types/react 与 @types/react-dom 或将它们与 react/react-dom 版本严格对齐;修复后贴回完整 tsc 输出以便确认。

src/Footer/index.tsx (1)

17-43: LGTM:Footer 改为泛型箭头函数实现,行为保持一致

类型与上下文依赖合理,useMemo 依赖项完整。无阻塞问题。

src/Body/index.tsx (1)

67-68: LGTM:perfRef 初始化更简洁

useRef<PerfRecord>({ renderWithProps: false }) 写法清晰,无行为变更。

src/Table.tsx (8)

194-198: 将 Table 重构为箭头组件并用 forwardRef 暴露:赞同

泛型边界与签名清晰,便于与 React 19 的类型配合。

Also applies to: 984-984


341-345: 统一以 null 初始化 useRef:正确且与 @types/react 18/19 一致

这些改动消除了历史上不显式初始化的潜在空值歧义。

Also applies to: 382-382, 397-401


336-338: 列上下文 useMemo:依赖与值匹配,OK


637-647: emptyNode 明确标注 ReactNode 泛型:OK

类型更准确,利于调用端推断。


867-875: 将 classNames 与 styles 注入 TableContext 并补齐依赖:很好

满足样式/类名动态刷新场景,与长期学习记录一致。

请确认上下游消费 TableContext 的组件(如 Header/Body/Cell)已读取并使用新增的 classNames/styles 字段。

Also applies to: 930-932


1002-1008: 为默认导出附加静态属性(EXPAND_COLUMN、INTERNAL_HOOKS、Column、ColumnGroup、Summary):OK

与公共 API 保持一致。请确认 FooterComponents 暴露了 Row/Cell 静态成员以满足 Table.Summary.Row/Cell 的现有用法。

Also applies to: 1018-1018


346-351: 修复 nativeElement 的可空性以匹配对外类型

fullTableRef.current 可能为 null,但 Reference.nativeElement 在类型上为 HTMLDivElement;严格模式会触发 TypeScript 错误。建议使用非空断言或将对外类型改为 HTMLDivElement | null。

位置:src/Table.tsx 行 346-351

  React.useImperativeHandle(ref, () => {
    return {
-      nativeElement: fullTableRef.current,
+      nativeElement: fullTableRef.current!,
      scrollTo: config => {
        if (scrollBodyRef.current instanceof HTMLElement) {

996-998: genTable 接收 CompareProps:已核实无外部影响

仓库搜索到定义与唯一调用:定义位于 src/Table.tsx:996,调用位于 src/Table.tsx:1000(const ImmutableTable = genTable();),调用处未传入 shouldTriggerRender;新增可选参数向后兼容,调用方无需修改。

@zombieJ
Copy link
Member

zombieJ commented Sep 15, 2025

@gemini-code-assist Pls help to CR again

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

你好!这是一个很棒的 PR,主要是将项目从 React 16 升级到了 React 19。大部分更改都是为了适应新版本的类型系统和 API,例如将函数组件转换为箭头函数形式、使用 React.FCPropsWithChildren、以及将 useRef 的初始值显式设置为 null。这些都是很好的现代化实践。

我在几个地方发现了一些可以改进的小问题,主要集中在类型安全和代码风格上。例如,在 src/hooks/useFrame.ts 中,setTimeout 的返回值类型应该是 ReturnType<typeof setTimeout> 而不是 number,以确保在 Node.js 和浏览器环境中的兼容性。另外,在 src/stickyScrollBar.tsx 中,useEffect 的清理函数中缺少了对 container 事件监听器的移除。这些修改将有助于提高代码的健壮性和可维护性。

总体而言,这次升级做得非常出色,代码库的现代化程度有了很大提升。感谢你的贡献!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/Panel/index.tsx (1)

8-15: 不透传 ...props 的做法更安全,避免无意事件绑定扩散

只解构 className/stylechildren 而不把 ...props 直接下发到 DOM,能有效规避外部误传事件处理器导致的多处绑定问题。此处做法认可。

🧹 Nitpick comments (1)
src/Panel/index.tsx (1)

8-15: 移除多余的 PropsWithChildren(React.FC 已自带 children)

@types/react 中,React.FC<P> 已经将 children 融入调用签名,再包一层 PropsWithChildren 属于冗余,易引入类型噪音。建议简化:

-const Panel: React.FC<React.PropsWithChildren<TitleProps>> = props => {
+const Panel: React.FC<TitleProps> = props => {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d7e33d and d286d53.

📒 Files selected for processing (2)
  • src/Footer/Row.tsx (1 hunks)
  • src/Panel/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Footer/Row.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: bbb169
PR: react-component/table#1202
File: src/Table.tsx:903-904
Timestamp: 2024-11-08T12:53:09.293Z
Learning: 在 `src/Table.tsx` 文件的 React 组件 `Table` 中,即使 `bodyScrollLeft` 频繁更新,也需要在 `TableContextValue` 的 `useMemo` 依赖数组中包含 `bodyScrollLeft` 和 `headerCellRefs`,因为每次滚动时重新计算 `TableContextValue` 是解决该问题所必须的。
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test / react component workflow
  • GitHub Check: test / react component workflow
🔇 Additional comments (1)
src/Panel/index.tsx (1)

8-15: 无需改动 — TitleProps 仅在仓库内声明与使用

仓库搜索结果:TitleProps 仅在 src/Panel/index.tsx 中声明(第3行)并仅在同文件用于 Panel(第8行);未发现其他引用或导出,因此原评论关于影响外部兼容性的担忧不成立。

Likely an incorrect or invalid review comment.

@zombieJ zombieJ merged commit 5599e70 into master Sep 15, 2025
13 checks passed
@zombieJ zombieJ deleted the react-19-update branch September 15, 2025 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants