class 组件中无限重新渲染循环的原因?

Cause of infinite re-render loop in a class component?

我对 React 比较陌生,我想了解我正在使用的这段代码是如何导致无限渲染循环的。我已经编写了下面显示问题的代码示例。我收到的错误消息是:“重新渲染次数过多。React 限制渲染次数以防止无限循环。”

传递给 DataTable 的 props 似乎是导致问题的原因。当其中一行被注释掉时,没有任何问题。但是,当 datapaginationDefaultPage 都传入时,就会出现无限循环。 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 docspaginationDefaultPage 道具是 number 类型,而不是 boolean。我认为您打算使用 paginationResetDefaultPage 道具,它是 boolean 类型。 paginationDefaultPage 的索引似乎从 1 开始,并且使用了无效的 属性,例如 false0-1"hi" 将导致无限 re-render 问题。

至于为什么会出现这种情况,是由于DataTable组件的实现。请记住,虽然 您的 组件中的状态可能不会更改,但用 React 编写的 third-party 组件将有自己的状态和(可能不是 bug-free)实现还有。