I am trying to render the responsive image grid, which might have images of different sizes. It sounds like the Masonry component is good fit for this case, but not sure that I am able to use this example in my application? It looks fully coupled to the place where it lives, I tried to take relevant parts, but I wasn't able to get working.
Also, I have tried to generate relevant code with wizard, and got this sample:
<AutoSizer>
{({ height, width }) => (
<CellMeasurer
cellRenderer={yourCellRenderer}
columnCount={numColumns}
rowCount={numRows}
width={width}
>
{({ getRowHeight }) => (
<Grid
cellRenderer={({ columnIndex, key, rowIndex, style }) => <div key={key} style={style}>...</div>}
columnCount={numColumns}
columnWidth={({ index }) => 100}
height={height}
rowCount={numRows}
rowHeight={getRowHeight}
width={width}
/>
)}
</CellMeasurer>
)}
</AutoSizer>
But what should I put instead of yourCellRenderer
, getRowHeight
?
Based on some samples in the internet I build following piece of code:
<div className="media-viewer" style={{height: "100vh"}}>
<AutoSizer>
{({height, width}) => (
<Grid
cellRenderer={({columnIndex, key, rowIndex, style}) => {
if (!result[rowIndex][columnIndex]) return <div key={key} style={style}></div>;
return (
<div key={key} style={style}>
<MediaItem key={result[rowIndex][columnIndex].id} app={app}
item={result[rowIndex][columnIndex]}/>
</div>
);
}}
columnCount={5}
columnWidth={250}
height={height}
rowCount={result.length}
rowHeight={250}
width={width}
/>
)}
</AutoSizer>
</div>
And the result it brings to the screen:
If someone able to provide me with robust example of responsive grid based on react-virtualize
, or point where I can improve my current code, I would appreciate that.
Best regards.
from the image you attached it seems like your images are not dynamically measured. consider adding this library
you need to add something like this:
const MasonryComponent = ({itemsWithSizes}) => {
function cellRenderer({index, key, parent, style}) {
const {item, size} = itemsWithSizes[index];
const height = columnWidth * (size.height / size.width) || defaultHeight;
return (
<CellMeasurer cache={cache} index={index} key={key} parent={parent}>
<div style={style}>
<img
src={item.image}
alt={item.title}
style={{
height: height,
width: columnWidth,
}}
/>
<h4>{item.title}</h4>
</div>
</CellMeasurer>
);
}
return (
<Masonry
cellCount={itemsWithSizes.length}
cellMeasurerCache={cache}
cellPositioner={cellPositioner}
cellRenderer={cellRenderer}
height={600}
width={800}
/>
);
};
// Render your grid
render(
<ImageMeasurer
items={noCacheList}
image={item => item.image}
defaultHeight={defaultHeight}
defaultWidth={defaultWidth}>
{({itemsWithSizes}) => <MasonryComponent itemsWithSizes={itemsWithSizes} />}
</ImageMeasurer>,
document.getElementById('root'),
);
if you would like, you can add a fiddle with your code for me (and the community) to take a look.
as for your questions regarding yourCellRenderer
and getRowHeight
;
yourCellRenderer
should call a function with is responsible for rendering a cell at any given index. it accepts the following parameters:
index, // Index of item within the collection
isScrolling, // The Grid is currently being scrolled
key, // Unique key within array of cells
parent, // Reference to the parent Grid (instance)
style, // Style object to be applied to cell (to position it);
// This must be passed through to the rendered cell element.
you can use cache.rowHeight
to get your specific height
if you would like a more tailored answer, feel free to add a snippet/fiddle with your code.
kind regards