只有当我更新数据两次时,React material-table 才会使用新数据重新渲染 table

React material-table is rerendering table with new data only if i update data twice

我正在使用用 React 构建的 material-table (https://material-table.com/#/)。

我有数据作为 material-table 的道具传入,如下面的代码所示。 我通常在父组件中单击一个按钮来更改 Performancetbl 组件中的 prop。但是,当我单击一次按钮时,table 不会重新呈现新数据。当我再次点击它时,它会重新呈现。为什么会这样?

我尝试将 props 保存到 Performancetbl 组件中的状态变量 state 中,但这根本没有改变行为。

我还尝试 console.log(props.datas) 看看我第一次点击按钮时是否出现了正确的数据。它确实是正确的值!你们能弄清楚为什么会这样吗?

function Performancetbl(props) {   
    const options = { 
        ...
    };
    console.log(props.datas)
    return(
        <div style={{ maxWidth: "100%" }}>
            <MaterialTable
                title="Overall"
                data={props.datas}
                columns={props.columns}        
                options={options}
                components={props.components}
            />
        </div>
    );
}

export default Performancetbl;

谢谢!

您最有可能发生这种情况的原因是您在数据到达之前渲染 table。

请参阅以下演示,了解如何从 API 中获取数据并通过 props 传递它。

You can view a live demo here


ParentComponent.js

import React, { useState } from "react";
import AppTable from "./AppTable";

export default function ParentComponent() {
  const [tableData, setTableData] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  const columns = [
    {
      title: "Id",
      field: "id"
    },
    {
      title: "UserId",
      field: "userId"
    },
    {
      title: "Title",
      field: "title"
    },
    {
      title: "Completed",
      field: "completed"
    }
  ];

  const tableDiv = {
    marginTop: "30px"
  };

  const shadowStyle = {
    boxShadow: "0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)"
  };

  const btnStyle = {
    height: "40px",
    width: "300px",
    fontSize: "24px",
    cursor: "pointer",
    ...shadowStyle
  };

  const headStyle = {
    textAlign: "center",
    padding: "20px",
    backgroundColor: "lightcoral",
    ...shadowStyle
  };

  const sleep = time => {
    return new Promise(resolve => setTimeout(resolve, time));
  };

  const fetchData = async () => {
    setIsLoading(true);
    // Add a timeout to give the appearance of long load times
    await sleep(3000);

    try {
      const resp = await fetch("https://jsonplaceholder.typicode.com/todos");
      const json = await resp.json();
      setTableData(json);
    } catch (err) {
      console.trace(err);
      alert(err.message + "\r\n\r\nSee console for more info.");
    }
    setIsLoading(false);
  };

  return (
    <div>
      <div style={headStyle}>
        <h1>Click button to get data</h1>
        <button style={btnStyle} onClick={fetchData}>
          Click Me To Get API Data
        </button>
      </div>
      <div style={tableDiv}>
        <AppTable data={tableData} columns={columns} isLoading={isLoading} />
      </div>
    </div>
  );
}

AppTable.js(使用material-table

import React from "react";
import MaterialTable from "material-table";
import tableIcons from "./TableIcons.js";

export default function AppTable({ data, columns, ...rest }) {
  return (
    <MaterialTable
      {...rest}
      icons={tableIcons}
      columns={columns}
      data={data}
    />
  );
}