When developing a component that requires grabbing DOM elements to calculate heights, I initially resorted to using a setTimeout function to ensure the elements are captured once the page loads. While this solution worked perfectly, I am aware that there might be a better approach than relying on setTimeout. I have heard that using useEffect could be a more efficient way to handle this. Here is the current implementation:
const OrderSummaryView = () => {
const isMobile = useGetBreakpoint() === 'mobile'
const { versionIsVariant } = useContext(Abtests.Context)
const isFixedScrollEnabled = versionIsVariant('FIXED_SCROLL_ORDER_SUMMARY') && !isMobile
const main = document.querySelector('main[class*="main"]')
const cartItemsContainer = document.querySelector('#cartItems')
const summaryContainer = document.querySelector('.summaryContainer')
const [scrollPosition, setScrollPosition] = useState(0)
const [itemContainerHeight, setItemContainerHeight] = useState(0)
const [summaryContainerHeight, setsummaryContainerHeight] = useState(0)
const [calculatedBreakpoint, setCalculatedBreakpoint] = useState(0)
const handleScroll = () => {
const position = window.pageYOffset
setScrollPosition(position)
}
useEffect(() => {
window.addEventListener('scroll', handleScroll, { passive: true })
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [])
setTimeout(() => {
setItemContainerHeight(cartItemsContainer.clientHeight)
if (summaryContainer.clientHeight !== 0) {
setsummaryContainerHeight(summaryContainer.clientHeight)
}
setCalculatedBreakpoint(itemContainerHeight - summaryContainerHeight + 100)
}, 2000)
const mainHeight = main.clientHeight
const isSticky = scrollPosition >= 90 && isFixedScrollEnabled && (scrollPosition < calculatedBreakpoint)
const isPostSticky = (scrollPosition >= calculatedBreakpoint) && isFixedScrollEnabled
const orderSummaryClassname = `orderSummary${isSticky ? `Div__is-sticky` : isPostSticky ? `Div__post-sticky` : 'Div'}`
const postStickyTop = `${mainHeight - summaryContainerHeight - 50}px`
return (
<div className="summaryContainer">
<div className={orderSummaryClassname}
style={isPostSticky ? { top: postStickyTop } : isSticky ? { top: '10px' } : null}>
<OrderSummaryTitle title="Order Summary" />
<OrderSummaryBody isFixedScrollEnabled={isFixedScrollEnabled} />
<DesignerCashback />
</div>
</div>
)
}
export default OrderSummaryView