class 组件中无限重新渲染循环的原因?
Cause of infinite re-render loop in a class component?
我对 React 比较陌生,我想了解我正在使用的这段代码是如何导致无限渲染循环的。我已经编写了下面显示问题的代码示例。我收到的错误消息是:“重新渲染次数过多。React 限制渲染次数以防止无限循环。”
传递给 DataTable 的 props 似乎是导致问题的原因。当其中一行被注释掉时,没有任何问题。但是,当 data
和 paginationDefaultPage
都传入时,就会出现无限循环。 data
作为道具传递给 CustomDataTable
,在此示例中,数据只是一个硬编码数组。
我目前的理解是,只有在状态改变时才应该重新渲染,但据我所知,状态没有改变(状态在 CustomDataTable 构造函数中初始化,但之后从未改变) .
我已经发布了下面的代码,但您也可以在这里查看:https://codesandbox.io/s/bitter-fire-g948qi
App.js
import "./styles.css";
import CustomDataTable from "./CustomDataTable";
// Utility function
function convertUnixTimestamp(timestamp) {
const d = new Date(timestamp);
const month = d.getMonth().toString().padStart(2, "0");
const date = d.getDate().toString().padStart(2, "0");
const hour = d.getUTCHours().toString().padStart(2, "0");
const minutes = d.getMinutes().toString().padStart(2, "0");
const seconds = d.getSeconds().toString().padStart(2, "0");
return `${d.getFullYear()}/${month}/${date} ${hour}:${minutes}:${seconds}`;
}
export default function App() {
const columns = [
{ name: "Import ID", selector: (row) => row[0], sortable: true },
{
name: "Timestamp",
selector: (row) => convertUnixTimestamp(row[1]),
sortable: true
}
];
return (
<div className="App">
<CustomDataTable
columns={columns}
data={[["239482398492839482", "2022-05-31 16:03"]]}
/>
</div>
);
}
CustomDataTable.js
import React from "react";
import DataTable from "react-data-table-component-with-filter";
class CustomDataTable extends React.Component {
constructor(props) {
super(props);
console.log("CustomDataTable constructor");
this.state = {
data: props.data,
filteredItems: props.data,
filterText: "",
resetPaginationToggle: false
};
}
render() {
// Uncommenting data={this.state.filteredItems} and commenting out paginationDefaultPage={this.state.resetPaginationToggle}
// prevents the infinite loop and shows the data as expected with no problems
// Commenting out data={this.state.filteredItems} and leaving paginationDefaultPage=
// {this.state.resetPaginationToggle} doesn't cause any problems
// Uncommenting both lines causes an infinite loop
return (
<DataTable
columns={this.props.columns}
// data={this.state.filteredItems}
paginationDefaultPage={this.state.resetPaginationToggle}
pagination
persistTableHead
subHeader
/>
);
}
}
export default CustomDataTable;
根据 React Data Table Component docs,paginationDefaultPage
道具是 number
类型,而不是 boolean
。我认为您打算使用 paginationResetDefaultPage
道具,它是 boolean
类型。 paginationDefaultPage
的索引似乎从 1
开始,并且使用了无效的 属性,例如 false
、0
、-1
或 "hi"
将导致无限 re-render 问题。
至于为什么会出现这种情况,是由于DataTable
组件的实现。请记住,虽然 您的 组件中的状态可能不会更改,但用 React 编写的 third-party 组件将有自己的状态和(可能不是 bug-free)实现还有。
我对 React 比较陌生,我想了解我正在使用的这段代码是如何导致无限渲染循环的。我已经编写了下面显示问题的代码示例。我收到的错误消息是:“重新渲染次数过多。React 限制渲染次数以防止无限循环。”
传递给 DataTable 的 props 似乎是导致问题的原因。当其中一行被注释掉时,没有任何问题。但是,当 data
和 paginationDefaultPage
都传入时,就会出现无限循环。 data
作为道具传递给 CustomDataTable
,在此示例中,数据只是一个硬编码数组。
我目前的理解是,只有在状态改变时才应该重新渲染,但据我所知,状态没有改变(状态在 CustomDataTable 构造函数中初始化,但之后从未改变) .
我已经发布了下面的代码,但您也可以在这里查看:https://codesandbox.io/s/bitter-fire-g948qi
App.js
import "./styles.css";
import CustomDataTable from "./CustomDataTable";
// Utility function
function convertUnixTimestamp(timestamp) {
const d = new Date(timestamp);
const month = d.getMonth().toString().padStart(2, "0");
const date = d.getDate().toString().padStart(2, "0");
const hour = d.getUTCHours().toString().padStart(2, "0");
const minutes = d.getMinutes().toString().padStart(2, "0");
const seconds = d.getSeconds().toString().padStart(2, "0");
return `${d.getFullYear()}/${month}/${date} ${hour}:${minutes}:${seconds}`;
}
export default function App() {
const columns = [
{ name: "Import ID", selector: (row) => row[0], sortable: true },
{
name: "Timestamp",
selector: (row) => convertUnixTimestamp(row[1]),
sortable: true
}
];
return (
<div className="App">
<CustomDataTable
columns={columns}
data={[["239482398492839482", "2022-05-31 16:03"]]}
/>
</div>
);
}
CustomDataTable.js
import React from "react";
import DataTable from "react-data-table-component-with-filter";
class CustomDataTable extends React.Component {
constructor(props) {
super(props);
console.log("CustomDataTable constructor");
this.state = {
data: props.data,
filteredItems: props.data,
filterText: "",
resetPaginationToggle: false
};
}
render() {
// Uncommenting data={this.state.filteredItems} and commenting out paginationDefaultPage={this.state.resetPaginationToggle}
// prevents the infinite loop and shows the data as expected with no problems
// Commenting out data={this.state.filteredItems} and leaving paginationDefaultPage=
// {this.state.resetPaginationToggle} doesn't cause any problems
// Uncommenting both lines causes an infinite loop
return (
<DataTable
columns={this.props.columns}
// data={this.state.filteredItems}
paginationDefaultPage={this.state.resetPaginationToggle}
pagination
persistTableHead
subHeader
/>
);
}
}
export default CustomDataTable;
根据 React Data Table Component docs,paginationDefaultPage
道具是 number
类型,而不是 boolean
。我认为您打算使用 paginationResetDefaultPage
道具,它是 boolean
类型。 paginationDefaultPage
的索引似乎从 1
开始,并且使用了无效的 属性,例如 false
、0
、-1
或 "hi"
将导致无限 re-render 问题。
至于为什么会出现这种情况,是由于DataTable
组件的实现。请记住,虽然 您的 组件中的状态可能不会更改,但用 React 编写的 third-party 组件将有自己的状态和(可能不是 bug-free)实现还有。