【问题标题】:How to rerender table with new columns and rows?如何用新的列和行重新渲染表?
【发布时间】:2020-09-14 18:32:30
【问题描述】:

我有一个带有 Material-UI 表的组件作为子组件。我想让用户选择他们想要显示的数据,按下按钮,然后将其显示在 Material-UI 表中。

数据不一定每次都具有相同的格式(例如,用户可能首先希望查看 NFL 球员列表及其统计数据。稍后他们希望查看比赛列表及其结果。)数据是从 API 中提取。

我已设置 Material-UI 表格组件以接受描述每个数据集的行数据和列详细信息的数组。然后,表格会根据这些参数自行构建。

我怎样才能完成这项任务?目前我将行和列数据存储在状态中。表格组件从状态设置其道具。当组件被加载时,效果被触发并且表格中填充了一些播放器数据。我有一个将 onClick 设置为函数的按钮,该函数将使用一些新的(和不同的数据)设置状态。但是,当我单击按钮时,我的数据消失了,并且我的标题保持在单击之前的状态。

父组件

import React, { useState, useEffect } from 'react';
import Table from './SimpleTable';
import { getDummyPlayerData } from '../api_helper/api'
import Button from '@material-ui/core/Button';


const getColumnDetailsFromData = (data) => {
  var columns = [];

  Object.keys(rows[0]).forEach((key, index) => {
    columns.push({
      id: key,
      label: key,
      align: "right",
      component: "",
      scope: ""
    })
  })

  columns[0].align = "";
  columns[0].component = "th";
  columns[0].scope = "row";

  return columns;
}

export default function ParentDisplayTable() {

  const [data, setData] = useState([]);
  const [colDetails, setColDetails] = useState([]);
  const [uid, setUid] = useState(['player_id'])

  useEffect(() => {
    getDummyPlayerData().then(result => {
      setData(result);
      setColDetails(getColumnDetailsFromData(data));
    })
  }, []);

  const updateTable = (event) => {
    const rows = [
      {
        att1: "hello",
        att2: "goodbye"
      },
      {
        att1: "aloha",
        att2: "aloha"
      }
    ]

    const cols = getColumnDetailsFromData(rows);

    const key = "att1"

    setData(rows);
    setColDetails(cols);
    setUid(key);
  }

  return (
    <div>
      <Button
        variant="contained"
        color="primary"
        margin="normal"
        onClick={e => updateTable(e)}
      >
        Update Table
        </Button>
        
      <Table
        columns={colDetails}
        rows={data}
        rowsUniqueKey={uid}

      ></Table>
    </div>
  )
}

表格组件

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';

const useStyles = makeStyles((theme) => ({
  table: {
    minWidth: 650
  },
  formControl: {
    margin: theme.spacing(1),
    minWidth: 250,
    maxWidth: 300,
  },
  chips: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  chip: {
    margin: 2,
  },
  noLabel: {
    marginTop: theme.spacing(3),
  },
}));


export default function SimpleTable(props) {
  const classes = useStyles();

  return (
    <div>
      <TableContainer component={Paper}>
        <Table className={classes.table} aria-label="simple table">
          <TableHead>
            <TableRow>
              {props.columns.map(({ ...column }) => (
                <TableCell
                  align={column.align}>
                  {column.label}
                </TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {props.rows.map((row) => (
              <TableRow key={row[props.rowsUniqueKey]}>
                {props.columns.map(({ ...column }) => (
                  <TableCell
                    component={column.component}
                    scope={column.scope}
                    align={column.align}>
                    {row[column.id]}
                  </TableCell>
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
}

更新前

更新后

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    我能够解决我自己的问题。该方法是正确的,但我在 getColumnDetailsFromData(data) 中出现错误,其中我尝试遍历“行”的键而不是“数据”(我传入的变量。)这似乎有效,因为我之前指定了一个数组rows[] 在发布问题之前我已经从代码中编辑出来,该函数正在使用该函数。因此,该表没有收到正确的列,因为它们是基于其他数据的。

    此外,我必须更改 useEffect 中的代码以从 API 调用的结果中获取列,而不是在 useState() 中指定的“数据”。这是因为在调用 getColumnDetailsFromData(data) 时“数据”未定义。我不确定为什么它是未定义的,因为上一行设置了状态。 (也许只有在 useEffect() 执行完成后才设置状态?):

      useEffect(() => {
        getDummyPlayerData("1").then(result => {
          setData(result);
          //setColDetails(getColumnDetailsFromData(data));
          setColDetails(getColumnDetailsFromData(result));
        })
      }, []);
    

    请参阅下面的工作代码:

    import React, { useState, useEffect } from 'react';
    import Table from './SimpleTable';
    import { getDummyPlayerData } from '../api_helper/api'
    import Button from '@material-ui/core/Button';
    
    const getColumnDetailsFromData = (data) => {
      var columns = [];
    
      Object.keys(data[0]).forEach((key, index) => {
        columns.push({
          id: key,
          label: key,
          align: "right",
          component: "",
          scope: ""
        })
      })
    
      columns[0].align = "";
      columns[0].component = "th";
      columns[0].scope = "row";
    
      return columns;
    }
    
    export default function ParentDisplayTable() {
    
      const [data, setData] = useState([]);
      const [colDetails, setColDetails] = useState([]);
      const [uid, setUid] = useState(['player_id'])
    
      useEffect(() => {
        getDummyPlayerData("1").then(result => {
          setData(result);
          setColDetails(getColumnDetailsFromData(result));
        })
      }, []);
    
      const updateTable = async (event) => {
        const result = await getDummyPlayerData("2");
        setData(result);
        setColDetails(getColumnDetailsFromData(result));
      }
    
      return (
    
        <div>
          <Button
            variant="contained"
            color="primary"
            margin="normal"
            onClick={e => updateTable(e)}
          >
            Update Table
            </Button>
    
          <Table
            columns={colDetails}
            rows={data}
            rowsUniqueKey={uid}
          ></Table>
        </div>
      )
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 2021-12-12
      • 2012-10-16
      • 1970-01-01
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      相关资源
      最近更新 更多