最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

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

发布评论

评论列表(0)

  1. 暂无评论