Closed jeffchuber closed 3 weeks ago
My solution is to add the columnCount
to each item so it's accessible through the props.data
.
This is a terrible solution. I'd love if the parent's metadata was forwarded to the render component.
Why not to pass index
prop in to renderer's function? Looks like it is simplest solution which not require additional calculations during rendering and we can access to renderer's data by data[index]
Here is an example of how this could be done
import { ComponentType, useCallback, useEffect, useState } from "react";
import AutoSizer from "react-virtualized-auto-sizer";
import { FixedSizeGrid as _FixedSizeGrid, FixedSizeGridProps } from "react-window";
const FixedSizeGrid = _FixedSizeGrid as ComponentType<FixedSizeGridProps>;
import './dataview.css'
const GUTTER_SIZE = 8;
const ROW_HEIGHT = 250;
const COLUMN_WIDTH = 250;
type CellProps = { columnIndex: number, rowIndex: number, style: React.CSSProperties };
export const GridComponent = () => {
const [cellData,setCellData] = useState<number[]>([...Array(100).keys()]);
const Cell = useCallback(({ columnIndex, rowIndex, style, columnCount }: CellProps & { columnCount: number }) => {
const index = rowIndex * columnCount + columnIndex;
if(index >= cellData.length) {
return null;
}
return (
<div style={{
...style,
background: '#333',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
left: style.left as number + GUTTER_SIZE,
top: style.top as number + GUTTER_SIZE,
width: style.width as number - GUTTER_SIZE,
height: style.height as number - GUTTER_SIZE,
}}>
<Typography>{cellData[index] + 1}</Typography>
</div>
)},[cellData]);
return (
<div style={{ width: '100%', height: '100%' }}>
<AutoSizer style={{ width: '100%', height: '100%' }}>
{({ height, width }) => {
const columnCount = Math.floor(width as number / (COLUMN_WIDTH+GUTTER_SIZE));
const rowCount = Math.ceil(cellData.length / columnCount);
return (
<FixedSizeGrid
height={height || 0}
width={width || 0}
columnCount={columnCount}
columnWidth={COLUMN_WIDTH+GUTTER_SIZE}
rowCount={rowCount}
rowHeight={ROW_HEIGHT+GUTTER_SIZE}
>
{(props: CellProps) => Cell({...props, columnCount})}
</FixedSizeGrid>
)
}}
</AutoSizer>
</div>
);
}
I am rendering a list as a grid.
Right now, I have my index to my itemData defined as
(rowIndex * 3) + columnIndex
- this is stable forcolumnCount
= 3. However I want to make the parent container resizable, and to increase the number ofcolumnCount
on resize. That pat is working, but I can't figure out how to pass any info about the currentcolumnCount
down to theCell
element. From the code, it looks like this is the only data that is exposed.https://github.com/bvaughn/react-window/blob/d80bef25fe706d0c73fc801674c086f681811190/src/createGridComponent.js#L15
Would it be possible to pass
columnCount
(and possiblyrowCount
as well) down to theRenderComponent
? This would allow me to do the relevant "math" in the component.Apologies if I missed something entirely obvious!