3

Implementing filters on React Virtualized Infinite Loader.Every Time the filter is applied, the filtered data appends to the already rendered row instead of rendering the filtered data in the table. Also Used Context API's to have a common source of truth.But basically the Virtualized table doesn't gets cleared.So what would be a better approach to go about it? New to React and Infinite Loader.Sharing the code:

Parent Component:-
import React from 'react';
import { Paper } from '@material-ui/core';
import { withApollo, compose } from 'react-apollo';
import CustomizedVirtualizedTable from '../../CustomizedVirtualizedTable';
import { WithContext } from '../../../HOCmiddleware/withcontext';

const rows = [];

const pushDataInRow = props => {
  let botsList = props && props.value.botsDataList.list;

  if (botsList) {
    for (let i = 0; i < botsList.length; i++) {
      let el = botsList[i];
      if (rows.indexOf(el) === -1) {
        rows.push(el);
      }
    }
  }
};
const isRowLoaded = ({ index }) => {
  return !!rows[index];
};

const headCells = [
  {
    dataKey: 'BotId',
    label: 'Bot ID',
    width: '150'
  },
  { dataKey: 'Status', numeric: false, label: 'Status', width: '150' },
  {
    dataKey: 'CurrentTask',
    label: 'Current Task',
    width: '150'
  },
  {
    dataKey: 'ChargeStatus',
    label: 'Charge Status',
    width: '150'
  },
  {
    dataKey: 'OperatingTime',
    disablePadding: false,
    label: 'Operating Time',
    width: '150'
  }
];

const VirtualizedBotsTable = props => {

  const totalDataCount = props.data.TotalBotCount;
  pushDataInRow(props);
  return (
    <Paper
      style={{
        height: 500,
        width: '100%',
        paddingLeft: '20px',
        boxSizing: 'border-box'
      }}
    >
      <CustomizedVirtualizedTable
        rowCount={rows.length}
        totalDataCount={totalDataCount}
        rowGetter={({ index }) => rows[index]}
        fetchDataQuery={props.fetchDataQuery}
        columns={headCells}
        isRowLoaded={isRowLoaded}
      />
    </Paper>
  );
};

export default compose(withApollo)(WithContext(VirtualizedBotsTable));


Child Component:-
import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { withStyles } from '@material-ui/core/styles';
import TableCell from '@material-ui/core/TableCell';
import Paper from '@material-ui/core/Paper';
import { AutoSizer, Column, Table, InfiniteLoader } from 'react-virtualized';
import { PAGE_LIMIT_SIZE } from '../constants/frontEndConstants';

const styles = theme => ({
  flexContainer: {
    display: 'flex',
    alignItems: 'center',
    boxSizing: 'border-box'
  },
  table: {
    // temporary right-to-left patch, waiting for
    // https://github.com/bvaughn/react-virtualized/issues/454
    '& .ReactVirtualized__Table__headerRow': {
      flip: false,
      paddingRight: theme.direction === 'rtl' ? '0px !important' : undefined
    }
  },
  tableRow: {
    cursor: 'pointer'
  },
  tableRowHover: {
    '&:hover': {
      backgroundColor: theme.palette.grey[200]
    }
  },
  tableCell: {
    flex: 1
  },
  noClick: {
    cursor: 'initial'
  }
});

class MuiVirtualizedTable extends React.PureComponent {
  static defaultProps = {
    headerHeight: 48,
    rowHeight: 48
  };
  constructor(props) {
    super();
    this.state = {
      totalDataCount: 0
    };
  }

  getRowClassName = ({ index }) => {
    const { classes, onRowClick } = this.props;

    return clsx(classes.tableRow, classes.flexContainer, {
      [classes.tableRowHover]: index !== -1 && onRowClick != null
    });
  };

  cellRenderer = ({ cellData, columnIndex }) => {
    const { columns, classes, rowHeight, onRowClick } = this.props;
    return (
      <TableCell
        component='div'
        className={clsx(classes.tableCell, classes.flexContainer, {
          [classes.noClick]: onRowClick == null
        })}
        variant='body'
        style={{ height: rowHeight }}
        align={
          (columnIndex != null && columns[columnIndex].numeric) || false
            ? 'right'
            : 'left'
        }
      >
        {cellData}
      </TableCell>
    );
  };

  isRowLoaded = ({ index }) => {
    return !!this.state.loadedData[index];
  };

  headerRenderer = ({ label, columnIndex }) => {
    const { headerHeight, columns, classes } = this.props;

    return (
      <TableCell
        component='div'
        className={clsx(
          classes.tableCell,
          classes.flexContainer,
          classes.noClick
        )}
        variant='head'
        style={{ height: headerHeight }}
        align={columns[columnIndex].numeric || false ? 'right' : 'left'}
      >
        <span>{label}</span>
      </TableCell>
    );
  };

  render() {
    const {
      classes,
      columns,
      rowHeight,
      headerHeight,
      totalDataCount,
      ...tableProps
    } = this.props;
    return (
      <InfiniteLoader
        isRowLoaded={this.props.isRowLoaded}
        loadMoreRows={this.props.fetchDataQuery}
        rowCount={totalDataCount}
        threshold={10}
      >
        {({ onRowsRendered, registerChild }) => (
          <AutoSizer>
            {({ height, width }) => (
              <Table
                height={height}
                width={width}
                rowHeight={rowHeight}
                gridStyle={{
                  direction: 'inherit'
                }}
                headerHeight={headerHeight}
                className={classes.table}
                {...tableProps}
                rowClassName={this.getRowClassName}
                ref={registerChild}
                onRowsRendered={onRowsRendered}
              >
                {columns.map(({ dataKey, ...other }, index) => {
                  return (
                    <Column
                      key={dataKey}
                      headerRenderer={headerProps =>
                        this.headerRenderer({
                          ...headerProps,
                          columnIndex: index
                        })
                      }
                      className={classes.flexContainer}
                      cellRenderer={this.cellRenderer}
                      dataKey={dataKey}
                      {...other}
                    />
                  );
                })}
              </Table>
            )}
          </AutoSizer>
        )}
      </InfiniteLoader>
    );
  }
}

MuiVirtualizedTable.propTypes = {
  classes: PropTypes.object.isRequired,
  columns: PropTypes.arrayOf(
    PropTypes.shape({
      dataKey: PropTypes.string.isRequired,
      label: PropTypes.string.isRequired,
      numeric: PropTypes.bool,
      width: PropTypes.number.isRequired
    })
  ).isRequired,
  headerHeight: PropTypes.number,
  onRowClick: PropTypes.func,
  rowHeight: PropTypes.number
};

const CustomizedVirtualizedTable = withStyles(styles)(MuiVirtualizedTable);
export default CustomizedVirtualizedTable;
NotSoTechie
  • 31
  • 1
  • 2

0 Answers0