reactjs - Issue Combining Virtualization with Expanding Sub-Rows in Material React Table - Stack Overflow

First of all, I’d like to express my admiration for this package—it’s incredibly flexible and thoughtfu

First of all, I’d like to express my admiration for this package—it’s incredibly flexible and thoughtfully designed

Recently, I implemented virtualization in one of my projects to handle a large dataset, using the example provided in your documentation: Infinite Scrolling Example. It worked flawlessly—thank you for this excellent guide!

However, my project also requires an expand-collapse functionality for rows. I attempted to combine the virtualization example with the Expanding Sub-Rows Guide. Unfortunately, I’ve encountered an issue where expanding a parent row does not display the sub-rows.

Problem: When I expand a parent row, the sub-rows don’t render correctly in the table.

Steps I Followed:

I used the infinite scrolling example to handle large datasets with virtualization. I integrated the expanding sub-rows functionality as described in the guide.

Question: Could you please provide guidance on how to properly combine these two features? Are there any specific adjustments or best practices needed to make them work seamlessly together?

Thank you in advance for your help, and I’m happy to provide additional details or code snippets if needed.

This is what i have so far code wise:

    const { data, fetchNextPage, isError, isFetching, isLoading } = useInfiniteQuery({
    queryKey: ['table-data', columnFilters, expanded, sorting],
    queryFn: async ({ pageParam = 0 }) => {
      const offset = pageParam * fetchSize;
  
      const preQueryFilters = props.preQueryRes.decompose()[0].rawData();
      let response,processedResp;
  
      const expandedRowId = Object.entries(expanded).find(([id, isExpanded]) => isExpanded)?.[0];
  
      if (isTriggeredByExpansion) { //checking if there is a change in expanded state
        console.log('Fetching subRows for expanded row:', expandedRowId);
  
        const id = expandedRowId.split('-').pop(); // Extract the last part of the ID . since i only allow one expansion at a time
        const [subDim,readyQuery] = addSubQueryFilter(props.query, id)
        response = await loadCubeData(readyQuery);
        try{
          processedResp = processData(response,subDim)
          processedResp = [..pleteData.current,...processedResp]
        }
        catch(e){
          console.log(e)
        }
      } else {
        console.log('Fetching top-level rows');
        response = await loadCubeData(addPreQueryResAsFilter(props.query, preQueryFilters.slice(offset, offset + fetchSize)));
        try{
          processedResp = processData(response)
          completeData.current=[..pleteData.current,...processedResp]
        }
        catch(e){
          console.log(e)
        }
        // completeData.current = processedResp; // Cache top-level data
      }
  
      return {
        data: processedResp,
        meta: { totalRowCount: preQueryFilters.length || 0 },
      };
    },
    initialPageParam: 0,
    getNextPageParam: (_lastGroup, groups) => groups.length,
    refetchOnWindowFocus: false,
     });
 
     const flatReportData = useMemo(() => {
    console.log('my data.....',data)

    const newData = data?.pages?.flatMap((page) => page.data) || [];
    return [...newData];
      }, [data]);
      <MaterialReactTable
            columns={tableColumns.current}
            data={flatReportData.filter((r) => !r.parentId)}
            enablePagination={false}
            enableRowVirtualization
            getRowId={(originalRow) => originalRow.id} // Use the `id` field as the unique identifier
            muiTableContainerProps={{
              ref: tableContainerRef,
              sx: { maxHeight: '600px' },
              onScroll: (event) => fetchMoreOnBottomReached(event.target),
            }}
            muiToolbarAlertBannerProps={isError ? { color: 'error', children: 'Error loading data' } : undefined}
            renderBottomToolbarCustomActions={() => (
              <Typography>
                Fetched {totalFetched} of {totalDBRowCount} total rows.
              </Typography>
            )}
            
            state={{
              expanded,
              columnFilters,
              isLoading,
              showAlertBanner: isError,
              showProgressBars: isFetching,
              sorting,
            }}
            rowVirtualizerInstanceRef={rowVirtualizerInstanceRef}
            rowVirtualizerOptions={{ overscan: 4 }}
            onColumnFiltersChange={setColumnFilters}
            onExpandedChange= {setExpanded}
            enableTopToolbar={false}
            enableExpanding
            getRowCanExpand =  {(row) => {return row.original.level < levels.length}} //just some type of boolean
            getSubRows={ (row) => {
              console.log('row-expanded',row,flatReportData,flatReportData.filter((r) => r.parentId === row.id)) 
              return flatReportData.filter((r) => r.parentId === row.id)
            }}
            onSortingChange={setSorting}
            paginateExpandedRows={false}
            enableColumnFilters={false}
            enableColumnActions={false}
            enableFullScreenToggle={false}
            enableDensityToggle={false}
            initialState={{ density: 'spacious' }}
            enableHiding={false}
           
          />

First of all, I’d like to express my admiration for this package—it’s incredibly flexible and thoughtfully designed

Recently, I implemented virtualization in one of my projects to handle a large dataset, using the example provided in your documentation: Infinite Scrolling Example. It worked flawlessly—thank you for this excellent guide!

However, my project also requires an expand-collapse functionality for rows. I attempted to combine the virtualization example with the Expanding Sub-Rows Guide. Unfortunately, I’ve encountered an issue where expanding a parent row does not display the sub-rows.

Problem: When I expand a parent row, the sub-rows don’t render correctly in the table.

Steps I Followed:

I used the infinite scrolling example to handle large datasets with virtualization. I integrated the expanding sub-rows functionality as described in the guide.

Question: Could you please provide guidance on how to properly combine these two features? Are there any specific adjustments or best practices needed to make them work seamlessly together?

Thank you in advance for your help, and I’m happy to provide additional details or code snippets if needed.

This is what i have so far code wise:

    const { data, fetchNextPage, isError, isFetching, isLoading } = useInfiniteQuery({
    queryKey: ['table-data', columnFilters, expanded, sorting],
    queryFn: async ({ pageParam = 0 }) => {
      const offset = pageParam * fetchSize;
  
      const preQueryFilters = props.preQueryRes.decompose()[0].rawData();
      let response,processedResp;
  
      const expandedRowId = Object.entries(expanded).find(([id, isExpanded]) => isExpanded)?.[0];
  
      if (isTriggeredByExpansion) { //checking if there is a change in expanded state
        console.log('Fetching subRows for expanded row:', expandedRowId);
  
        const id = expandedRowId.split('-').pop(); // Extract the last part of the ID . since i only allow one expansion at a time
        const [subDim,readyQuery] = addSubQueryFilter(props.query, id)
        response = await loadCubeData(readyQuery);
        try{
          processedResp = processData(response,subDim)
          processedResp = [..pleteData.current,...processedResp]
        }
        catch(e){
          console.log(e)
        }
      } else {
        console.log('Fetching top-level rows');
        response = await loadCubeData(addPreQueryResAsFilter(props.query, preQueryFilters.slice(offset, offset + fetchSize)));
        try{
          processedResp = processData(response)
          completeData.current=[..pleteData.current,...processedResp]
        }
        catch(e){
          console.log(e)
        }
        // completeData.current = processedResp; // Cache top-level data
      }
  
      return {
        data: processedResp,
        meta: { totalRowCount: preQueryFilters.length || 0 },
      };
    },
    initialPageParam: 0,
    getNextPageParam: (_lastGroup, groups) => groups.length,
    refetchOnWindowFocus: false,
     });
 
     const flatReportData = useMemo(() => {
    console.log('my data.....',data)

    const newData = data?.pages?.flatMap((page) => page.data) || [];
    return [...newData];
      }, [data]);
      <MaterialReactTable
            columns={tableColumns.current}
            data={flatReportData.filter((r) => !r.parentId)}
            enablePagination={false}
            enableRowVirtualization
            getRowId={(originalRow) => originalRow.id} // Use the `id` field as the unique identifier
            muiTableContainerProps={{
              ref: tableContainerRef,
              sx: { maxHeight: '600px' },
              onScroll: (event) => fetchMoreOnBottomReached(event.target),
            }}
            muiToolbarAlertBannerProps={isError ? { color: 'error', children: 'Error loading data' } : undefined}
            renderBottomToolbarCustomActions={() => (
              <Typography>
                Fetched {totalFetched} of {totalDBRowCount} total rows.
              </Typography>
            )}
            
            state={{
              expanded,
              columnFilters,
              isLoading,
              showAlertBanner: isError,
              showProgressBars: isFetching,
              sorting,
            }}
            rowVirtualizerInstanceRef={rowVirtualizerInstanceRef}
            rowVirtualizerOptions={{ overscan: 4 }}
            onColumnFiltersChange={setColumnFilters}
            onExpandedChange= {setExpanded}
            enableTopToolbar={false}
            enableExpanding
            getRowCanExpand =  {(row) => {return row.original.level < levels.length}} //just some type of boolean
            getSubRows={ (row) => {
              console.log('row-expanded',row,flatReportData,flatReportData.filter((r) => r.parentId === row.id)) 
              return flatReportData.filter((r) => r.parentId === row.id)
            }}
            onSortingChange={setSorting}
            paginateExpandedRows={false}
            enableColumnFilters={false}
            enableColumnActions={false}
            enableFullScreenToggle={false}
            enableDensityToggle={false}
            initialState={{ density: 'spacious' }}
            enableHiding={false}
           
          />

Share Improve this question asked Nov 20, 2024 at 12:01 Hassan AkhlaqHassan Akhlaq 4451 gold badge4 silver badges13 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

i was able to solve my removing some of the properties in Material React table.

these are my new properties.

 const table = useMaterialReactTable({
  columns: tableColumns.current,
  data: flatReportData,
  enablePagination: false,
  enableRowVirtualization: true,
  enableEditing: true,
  manualFiltering: true,
  getRowId: (originalRow) => originalRow.id,
  muiTableContainerProps: {
    ref: tableContainerRef,
    sx: { maxHeight: '600px' },
    onScroll: (event) => fetchMoreOnBottomReached(event.target),
  },
  muiToolbarAlertBannerProps: isError
    ? { color: 'error', children: 'Error loading data' }
    : undefined,
  renderBottomToolbarCustomActions: () => (
    <Typography>
      Fetched {totalFetched} of {totalDBRowCount} total rows.
    </Typography>
  ),
  state: {
    expanded,
    // globalFilter,
    isLoading: false,
    showAlertBanner: isError,
    showProgressBars: isFetching,
    sorting,
    showSkeletons: false,
  },
  rowVirtualizerInstanceRef,


  enableExpandAll: false,
  enableColumnFilters: false,
  enableColumnActions: false,
  enableFullScreenToggle: false,
  enableDensityToggle: false,
  positionActionsColumn: 'last',
  initialState: { 
    // columnPinning: { left: ['mrt-row-actions'], right: [] },
    // density: 'compact' 
  },
  enableHiding: false,
  rowVirtualizerOptions: { overscan: 10 },
  // onGlobalFilterChange: setGlobalFilter,
  onExpandedChange: setExpanded,
  enableTopToolbar: false,
  enableExpanding: true,
  getRowCanExpand: (row) => row.original.level < levels.length,
  getSubRows: (row) =>
    data?.pages
      ?.flatMap((page) => page.data)
      .filter((r) => r.parentId === row.id),
  onSortingChange: setSorting,
  renderRowActions: ({ row, staticRowIndex, table }) => (
    row.original.level > 1 ? (
      <Box sx={{ display: 'flex', gap: '1rem' }}>
      <Tooltip title="Get more rows">
        <IconButton >
          <EditIcon />
        </IconButton>
      </Tooltip>
   
      
    </Box>
    ) :(<></>)
    
    ),
  muiTableHeadCellProps: {
    sx: {
      color: `${theme.palette.text.rowHeader}`,
      border: 'none',
      paddingTop: '2rem',
      paddingBottom: '1.5rem',
    },
  },
  muiTablePaperProps: {
    sx: {
      boxShadow: 'none',
    },
  },
  muiTopToolbarProps: {
    sx: {
      backgroundColor: `${theme.palette.background.paper}`,
    },
  },
  muiTableHeadRowProps: {
    sx: {
      backgroundColor: `${theme.palette.background.paper}`,
      color: `${theme.palette.text.rowHeader}`,
    },
  },
  muiTableBodyCellProps: {
    sx: {
      border: 'none',
      color: `${theme.palette.text.tableDetail}`,
      paddingTop: '1.0rem',
      paddingBottom: '1.0rem',
    },
  },
  muiTableBodyProps: {
    sx: {
      '& tr:nth-of-type(odd)': {
        backgroundColor: `${theme.palette.background.tableRow}`,
      },
      '& tr:nth-of-type(even)': {
        backgroundColor: `${theme.palette.background.paper}`,
      },
    },
  },
  muiTablePaginationProps: {
    sx: {
      '& .MuiTablePagination-select': {
        paddingTop: '1.2rem',
      },
    },
  },
  muiBottomToolbarProps: {
    sx: {
      '&.MuiToolbar-root': {
        minHeight: '5rem',
        backgroundColor: `${theme.palette.background.paper}`,
        color: `${theme.palette.text.tableDetail}`,
      },
    },
  },
});

Hope that helps

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742359421a4429092.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信