Masonry component with async measurements
See original GitHub issueThe doc says
Support for this may be added in the future but for now the use of the CellMeasurer render callback’s async measure parameter is not supported.
Following is my way to use async measurements by modifying the cellRenderer with measure
parameter.
- suppose there is a components can lazy load image and has a callback method once it is loaded.
<LazyLoadImage loadedCallback={callbackFn} src={some url} />
- use a function instead of a plain component as the child of
CellMeasurer
const cellRenderer = ({ index, key, parent, style }) => {
const material = materials[index]
return (
<CellMeasurer
cache={this.cache}
index={index}
key={key}
parent={parent}
>
{
({ measure }) => {
const updateFn = () => {
measure()
debouncedRecompute()
}
return (
<LazyLoadImage
loadedCallback={updateFn} width={(width - 40) / 5} src={material.url_128} />
)
}
}
</CellMeasurer>
)
}
- before that
const {
materials, width
} = this.props
- and
const debouncedRecompute = debounce(this.shouldRecompute, 250) // lodash.debounce
- at last
shouldRecompute () {
const { width } = this.props
if (this.masRef) { // masRef is the ref of this Masonry component
// <Masonry ref={ele => (this.masRef = ele)} ... />
this.cellPositioner.reset({
columnCount: 5,
columnWidth: (width - 40) / 5,
spacer: 10
})
this.masRef.recomputeCellPositions()
}
}
- about this.cache and this.cellPositioner
constructor (props) {
super(props)
const {
width
} = this.props
const cache = new CellMeasurerCache({
defaultHeight: 250,
defaultWidth: (width - 240) / 5,
fixedWidth: true
})
this.cache = cache
this.cellPositioner = createMasonryCellPositioner({
cellMeasurerCache: cache,
columnCount: 5,
columnWidth: (width - 40) / 5,
spacer: 10
})
this.shouldRecompute = this.shouldRecompute.bind(this)
}
hope it helps
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (2 by maintainers)
Top Results From Across the Web
Async loading of components in react-virtualized?
When the masonry is scrolling you can render a place holder instead of the cell content: if (isScrolling) return ( <div>placeholder</div> );.
Read more >Writing a React Native Image Masonry Component from Scratch
Checkout this blog on writing a pure JS React / React Native image masonry component without any third party libraries.
Read more >Element: <oj-masonry-layout> - Oracle
Masonry tiles can be of pre-defined sizes spanning 1 to 3 columns and rows. There is a specific style class for each of...
Read more >React Masonry Layout Component Powered By CSS - Morioh
A Masonry component leveraging CSS & native React rendering, for fast, respon. ... Optional, different gutter size on mobile */ @media (max-width: 800px) ......
Read more >How to use Masonry in react-virtualized - Javascript - Tabnine
After measurement is complete (componentDidMount or componentDidUpdate) this component evaluates positioned cells in order to determine if another measurement ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@PabloMessina You can also get the image sizes using an Image() instance’s
.onload
event. In this example I have an array of json objects which represents my image feed items (the title, description, some other information, as well as the image urls for the images to be used in the feed). You can see here that I process through every item in myfeedData
array, and then I load the image using javascript (var img = new Image(); img.src = feedItem.thumbnailUrl;
).I then define a function in this image instance’s
onload
event. When theonload
event fires, it means the image has been downloaded, meaning its properties have been populated with information (.height
, .width
, etc.) You can use this information to prepare your data for the grid (or if you are using an array of image urls, create an array of objects containing all of this data). In thisonload
function I see what the width and the height of the images are and inject this information as a new property into each feed item explicitly, so when I go to use them in my Masonry grid I know exactly what the widths and heights are. I also am storing the height to width ratio asheightRatio
, so if I have responsive column sizes in the grid I can calculate what the height should be for each image at any given column width. (I determine the column widths through querying for the screensize, etc.). You can see I also set this data into state once the last feed item has been processed, and thus once I have all of the information I need.For example:
@davidwu220, I ended up implementing a scrapper that would fetch all image dimensions off-line and save the dimensions in a .json file. The code I used is more or less like this:
Then my backend server would read the dimensions from the .json file and send the info to the React app before the masonry component is loaded.