React 18.2下Silevis/Reactgrid编辑单元格报t is undefined错误
问题描述
- 技术栈:React 18.2 + TypeScript
- 安装
@silevis/reactgrid组件库时,必须添加--legacy-peer-deps参数才能绕过peer依赖校验完成安装 - 异常现象:网格组件可正常渲染加载,但双击单元格尝试进入编辑状态时,持续抛出
"t is undefined"运行时错误 - 测试代码取自Reactgrid 4.0官方入门示例
复现代码
import * as React from "react"; import { render } from "react-dom"; import { ReactGrid, Column, Row } from "@silevis/reactgrid"; import "@silevis/reactgrid/styles.css"; import "./styles.css"; interface Person { name: string; surname: string; } const getPeople = (): Person[] => [ { name: "Thomas", surname: "Goldman" }, { name: "Susie", surname: "Quattro" }, { name: "", surname: "" } ]; const getColumns = (): Column[] => [ { columnId: "name", width: 150 }, { columnId: "surname", width: 150 } ]; const headerRow: Row = { rowId: "header", cells: [ { type: "header", text: "Name" }, { type: "header", text: "Surname" } ] }; const getRows = (people: Person[]): Row[] => [ headerRow, ...people.map<Row>((person, idx) => ({ rowId: idx, cells: [ { type: "text", text: person.name }, { type: "text", text: person.surname } ] })) ]; function App() { const [people] = React.useState<Person[]>(getPeople()); const rows = getRows(people); const columns = getColumns(); return <ReactGrid rows={rows} columns={columns} />; } render(<App />, document.getElementById("root"));
控制台错误栈
Ml@http://localhost:3000/static/js/bundle.js:9899:11 updateReducer@http://localhost:3000/static/js/bundle.js:34126:26 useReducer@http://localhost:3000/static/js/bundle.js:35337:20 useReducer@http://localhost:3000/static/js/bundle.js:50736:25 Al@http://localhost:3000/static/js/bundle.js:9923:46 renderWithHooks@http://localhost:3000/static/js/bundle.js:33775:31 updateFunctionComponent@http://localhost:3000/static/js/bundle.js:36975:24 beginWork@http://localhost:3000/static/js/bundle.js:38922:20 beginWork$1@http://localhost:3000/static/js/bundle.js:44670:18 performUnitOfWork@http://localhost:3000/static/js/bundle.js:43828:16 workLoopSync@http://localhost:3000/static/js/bundle.js:43741:26 renderRootSync@http://localhost:3000/static/js/bundle.js:43710:11 recoverFromConcurrentError@http://localhost:3000/static/js/bundle.js:43118:38 performConcurrentWorkOnRoot@http://localhost:3000/static/js/bundle.js:43019:26 workLoop@http://localhost:3000/static/js/bundle.js:52137:46 flushWork@http://localhost:3000/static/js/bundle.js:52111:18 performWorkUntilDeadline@http://localhost:3000/static/js/bundle.js:52395:25 Al@http://localhost:3000/static/js/bundle.js:9919:11 div div n@http://localhost:3000/static/js/bundle.js:10032:29 Dl@http://localhost:3000/static/js/bundle.js:10056:11 ya@http://localhost:3000/static/js/bundle.js:8328:11 n@http://localhost:3000/static/js/bundle.js:8884:29 App@http://localhost:3000/static/js/bundle.js:75:66
问题根因
@silevis/reactgrid 4.0.x 版本的peer依赖明确限定React版本范围为^17.0.0,内部实现依赖React 17的钩子调用顺序规则。在React 18的并发渲染调度逻辑下,双击单元格触发编辑态时,组件内部useReducer的上下文引用丢失;生产环境构建代码压缩后该引用被混淆命名为t,因此抛出t is undefined的运行时错误。
解决方案
- 优先方案(长期可用):升级
@silevis/reactgrid到4.1.0及以上稳定版本,执行安装命令npm install @silevis/reactgrid@latest即可。该版本已正式完成React 18适配,无需添加--legacy-peer-deps参数即可正常安装,上述官方示例代码无需修改即可正常运行单元格编辑功能。 - 临时兼容方案(仅用于紧急验证,不推荐生产环境使用):
- 移除项目根组件外层的
<React.StrictMode>包裹,关闭React 18的严格模式双调用机制 - 若使用React 18新增的
createRootAPI渲染根节点,临时换回React 17风格的react-dom/render方法渲染,可临时规避该错误
- 移除项目根组件外层的
内容的提问来源于stack exchange,提问作者Ed Zehoo

