【发布时间】:2020-09-28 00:45:59
【问题描述】:
我有一个组件,它在其中呈现一个 react-tabulator 组件。
如果我尝试渲染此组件的 2 个实例,则 Tabulator 在 Storybook 内部时会引发错误,并且在使用目标应用程序多次实例化包装器组件时,会引发相同的错误,但针对 'setColumns' 而不是 'destroy'。
TypeError: Cannot read property 'destroy' of null
at default_1.push../node_modules/react-tabulator/lib/ReactTabulator.js.default_1.componentWillUnmount (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:231022:20)
at callComponentWillUnmountWithTimer (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:214466:12)
at HTMLUnknownElement.callCallback (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:195074:14)
at Object.invokeGuardedCallbackDev (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:195123:16)
at invokeGuardedCallback (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:195178:31)
at safelyCallComponentWillUnmount (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:214473:5)
at commitUnmount (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:214995:11)
at commitNestedUnmounts (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:215049:5)
at unmountHostComponents (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:215329:7)
at commitDeletion (http://localhost:6006/vendors~main.72ccccb1e4a331ed682e.bundle.js:215386:5)
我已经在不同的环境中尝试过,例如在 Storybook 中:
export const BasicTable = () => (
<>
<Table isEditable={true} data={data} schema={schemaSmall} />
<Table isEditable={true} data={data} schema={schemaSmall} />
</>
);
架构或数据没有问题,因为如果只有 1 个实例,两者都会正确呈现。
包装器组件是一个 React 功能组件,它利用 useRef 钩子来引用 React-Tabulator 实例,这两个钩子引用是否可能发生冲突?
这是来自一个相当大的组件,但 Table.jsx 中的(IMO)相关部分是:
import 'react-tabulator/lib/styles.css';
import 'react-tabulator/lib/css/tabulator.min.css';
import { reactFormatter, ReactTabulator } from 'react-tabulator';
const Table = ({
data,
schema,
}) => {
const ref = useRef();
const [tableColumns, setTableColumns] = useState([]);
// is only running once per instance
useEffect(() => {
// builds an array of columns
setTableColumns(array);
}, [amEditing]
const options = {
history: true,
layoutColumnsOnNewData: true,
virtualDom: false,
};
return (
<StyledWrapper style={{ width }}>
<ReactTabulator
ref={ref}
columns={tableColumns}
data={[]}
options={options}
/>
</StyledWrapper>
);
};
结果:如果以单数形式使用,Table.jsx 组件在任一环境中都没有错误。
结果:Table.jsx 组件可以与原始 React-Tabulator 组件的多个实例一起正常工作。
如果是 useRef 钩子,那么有没有办法解决这个问题? 我看不出任何其他可能导致此失败的原因
更新 1: 我通过在 Table.jsx 组件中复制 react-tabulator 实例来测试 useRef 理论,并给每个不同的 ref:
const ref = useRef();
const ref1 = useRef();
但这仍然不起作用,并且在一个 Table.jsx 实例中引发了同样的错误。 (并且无论如何都不会解决这个问题,因为需要未知数量的实例化)。
更新 2: 在帮助下,我设法缩小了问题的范围。当 Table.jsx 被实例化时,它被传递了一个模式和数据,模式在内部被解析以构建一个应用于钩子的列数组:
const [columns, setColumns] = useState([])
列然后在 ReactTabulator 的声明中被引用。
当运行 Table.jsx 的单个实例时,这完全可以正常工作,但是当运行多个实例时,它会崩溃。
结果:
- 如果输出到 setColumns 的动态数组被复制并直接应用到 ReactTabulator 则没有问题 - 没有卸载
- 如果输出到 setColumns 的动态数组被复制并设置为钩子的初始值,那么问题仍然存在 - 卸载发生
虽然我的错误是“null”,但这并没有向我解释,因为它始终存在,并且列挂钩具有默认的空数组。
【问题讨论】:
标签: reactjs react-hooks tabulator react-functional-component