如何在react / typescript

问题描述

我有一个表,该表必须显示从接收到的数据动态生成的任意数量的列。

我创建了一个列接口,该接口将保存我需要的每个列的所有属性,例如是否可以将列最小化(变窄),是否是必须从结构中呈现图标的列或为组行渲染特定数据等。

在材料表中,我试图映射这些列,但始终会收到错误错误:this.tableContainerDiv.current为空

即使对象列表与我对这些列进行硬编码时完全相同,也会发生这种情况。

我的(缩减)代码

interface IColumnObject {
  field: string;
  title: string;
  sorting: boolean;
  minimizing: boolean;
  minimized: boolean;
  hidden: boolean;
  width: string;
  grouprender: boolean;
  iconrender: boolean;
}

interface State {
  detailData: ITableData[];
  filteredData: ITableData[];
  headers: IHeaderObject[];
  columns: IColumnObject[];
  filterList: IFilterList;
  anchorEl: Element;
  csvHeader: ICsvHeader[];
  csvData: ICsvData[];
}

class DetailAllRoute extends React.Component<Props,State> {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  private csvLink: React.RefObject<any> = React.createRef();
...
  public generateTableDetailData = () => {
    const tableData: ITableData[] = [];
    let createHeader = true;
    let createColumn = true;
    const headers: IHeaderObject[] = [];
    const columns: IColumnObject[] = [];
...
    // Add the Application,Filename and Location column objects to the columns list
    const applicationColumn: IColumnObject = {
      field: 'application',title: this.i18n.translatetoString('Column_Application'),sorting: true,minimizing: false,minimized: false,hidden: false,width: '100px',grouprender: false,iconrender: false,};

    columns.push(applicationColumn);

    const filenameColumn: IColumnObject = {
      field: 'filename',title: this.i18n.translatetoString('Column_Filename'),width: '270px',grouprender: true,};

    columns.push(filenameColumn);

    const locationColumn: IColumnObject = {
      field: 'location',title: this.i18n.translatetoString('Column_Location'),minimizing: true,width: '350px',};

    columns.push(locationColumn);
  ...
  }

  render() {
    const { classes } = this.props;
    const {
      compData,filteredData,columns,filterList,anchorEl,} = this.state;

    return (
      <React.Fragment>
        <Paper className={classes.muiListRoot} style={{ backgroundColor: '#fff' }}>
          <MaterialTable
            title={
              <span style={{ fontSize: '2.0em',fontWeight: 'bold',color: '#19768B' }}>
                {`${this.i18n.translatetoString('Table_DetailData')} Test`}
              </span>
            }
            actions={[
              {
                icon: FilterList,tooltip: 'Filter',position: 'toolbar',onClick: event => {
                  this.handlePopoverClick(event);
                },},]}
            components={{
              // eslint-disable-next-line react/display-name
              Header: headerprops => (
                <React.Fragment>
                  {this.getTableHeader()}
                  <MTableHeader {...headerprops} />
                </React.Fragment>
              ),}}
            columns={columns.map(c => {
              return {
                title: c.title,field: c.field,sorting: c.sorting,width: c.width,hidden: c.hidden,} as Column<any>;
            })}
            data={filteredData}
            parentChildData={(row,rows) => rows.find(a => a.application === row.parent)}
            options={{
              toolbar: true,exportButton: { csv: true },exportCsv: () => {
                this.customExportCSV();
              },headerStyle: {
                backgroundColor: '#19768B',color: 'white',borderBottom: '1px solid black',// eslint-disable-next-line @typescript-eslint/no-explicit-any
              rowStyle: (_data: any,index: number) => {
                return index % 2 ? { backgroundColor: '#ecf2f9' } : {};
              },}}
            localization={{
              pagination: {
                labeldisplayedRows: this.i18n.translatetoString('String_RowFromToCount'),labelRowsSelect: this.i18n.translatetoString('String_Rows'),labelRowsPerPage: this.i18n.translatetoString('String_RowsPerPage'),firstAriaLabel: this.i18n.translatetoString('String_FirstPage'),firstTooltip: this.i18n.translatetoString('String_FirstPage'),prevIoUsAriaLabel: this.i18n.translatetoString('String_PrevPage'),prevIoUsTooltip: this.i18n.translatetoString('String_PrevPage'),nextAriaLabel: this.i18n.translatetoString('String_NextPage'),nextTooltip: this.i18n.translatetoString('String_NextPage'),lastAriaLabel: this.i18n.translatetoString('String_LastPage'),lastTooltip: this.i18n.translatetoString('String_LastPage'),toolbar: {
                nRowsSelected: this.i18n.translatetoString('String_RowsSelected'),searchTooltip: this.i18n.translatetoString('String_Search'),searchPlaceholder: this.i18n.translatetoString('String_Search'),exportTitle: this.i18n.translatetoString('String_Export'),exportCSVName: this.i18n.translatetoString('String_ExportAs'),body: {
                emptyDataSourceMessage: this.i18n.translatetoString('String_NoData'),}}
          />
        </Paper>
        <div>
          <CSVLink
            data={csvData}
            headers={csvHeader}
            filename="CSV_File.csv"
            ref={this.csvLink}
            target="_blank"
          />
        </div>
      </React.Fragment>
    );
  }
}

您知道我在映射中做错了什么吗?还是当使用地图生成列数组时,材料表不喜欢它?

当我用以下方式对列进行硬编码时:

    ...
            columns={[
              {
                title: this.i18n.translatetoString('Column_Application'),field: 'application',hidden: true,{
                title: this.i18n.translatetoString('Column_Filename'),field: 'filename',// eslint-disable-next-line react/display-name
                render: rowData =>
                  !!!rowData.filename ? (
                    <span>
                      <b>{this.i18n.translatetoString('Column_Application')}: </b>
                      {rowData.application}
                    </span>
                  ) : (
                    rowData.filename
                  ),{
                title: this.i18n.translatetoString('Column_Location'),field: 'location',]}
    ...

一切正常。但是我需要映射列,因为列是根据接收到的数据动态生成的。

解决方法

在大多数情况下,问题是程序员错误。我花了好一会儿才弄清楚,但最终得到了同事的帮助。在他的指导下,我终于设法弄清了问题的根源。

最后,我发现系统抛出错误,因为找不到列名。控制台中显示的(更高处)错误非常容易引起误解,因为它指出使用了无效的(空)引用,事实并非如此。由于某种未知的原因,我无意中没有在最后一步中使用生成的唯一列名,在该步骤中我添加了每一行的数据,而是使用了硬编码的列名。容易忽略,但是却很难咬...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...