Skip to content

Instantly share code, notes, and snippets.

@Alynva
Last active Aug 10, 2019
Embed
What would you like to do?
An short script to craete a Masonry layout
import React, { useEffect } from "react";
import ReactDOM from 'react-dom';
import { useRefCallback } from "../utils";
export default function MasonryPage({children, numCols = 2}) {
const [masonryRef, setMasonryRef] = useRefCallback()
useEffect(() => {
const colHeights = Array(numCols).fill(0)
const container = ReactDOM.findDOMNode(masonryRef.current)
Array.from(container.children).forEach(child => {
const order = colHeights.indexOf(Math.min(...colHeights))
child.style.order = order
child.style.width = `${100/numCols}%`
colHeights[order] += parseFloat(child.clientHeight)
})
container.style.height = `${Math.max(...colHeights)}px`
}, [])
return (
<div className="d-flex flex-wrap flex-column" ref={setMasonryRef}>
{children}
</div>
)
}
import {
useRef,
useCallback
} from "react";
export default function useRefCallback(attach = null, detach = null) {
const ref = useRef(null)
const setRef = useCallback(node => {
if (ref.current) {
// Make sure to cleanup any events/references added to the last instance
attach && attach()
}
if (node) {
// Check if a node is actually passed. Otherwise node would be null.
// You can now do what you need to, addEventListeners, measure, etc.
detach && detach()
}
// Save a reference to the node
ref.current = node
}, [])
return [ref, setRef]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment