Open dimitar-nikovski opened 5 years ago
I am not using hooks, is there any way that I can use this hack? I am currently using setState to set children to render but initial layout is overlapping. If I updateLayout 1 seconds later using setTimeout, it works.
@berkayk if you are using setState this means and async update is scheduled, so your previous render doesn't have the children? It depends on where you are calling setState, I would recommend putting the data which the grid depends on into props either in its parent component or extract it into a thin SFC with the hook above, which contains only that and other props which go to StackGrid
Im using this in children component and it works smoothly
https://github.com/maslianok/react-resize-detector
<StackGrid
gridRef={grid => this.grid = grid}
columnWidth={width <= 768 ? '100%' : '33.33%'}
gutterWidth={15}
gutterHeight={15}
monitorImagesLoaded={true}>
<ReactResizeDetector
handleWidth
handleHeight
onResize={() => {
if (this.grid) {
this.grid.updateLayout();
}
}}>
<div>
<img />
</div>
</ReactResizeDetector>
</StackGrid>
Instead of the requestanimationframe hack, you can use useRef to store a class variable.
const firstUpdate = useRef(true);
useEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
if (grid.current) {
grid.current.updateLayout();
}
}, [element.width, element.stack.sizes]);
That's very helpful. I tweaked the solution slightly to trigger grid.current.updateLayout
each time an image's onLoad
event was triggered, ensuring that delayed load times doesn't affect it. E.g.
useEffect(() => {
if( grid.current ){
grid.current.updateLayout();
}
}, [imageLoadCounter])
I found that this works by updating the layout after 1 animation frame: