I'm referencing an element in a hook that measures the elements dimensions. When I first load the page. The element reference number logs undefined, but then defines itself.
The dimensions are used to position an absolutely positioned element into the center. When the page first loads, the element is centered. As the window size is changed, the element remains centered.
However, when I click a NavLink from react-dom-router and click back to the home page where the element reference belongs, the reference logs as undefined without later defining it self. The element is not centered until I resize the page.
My setup is:
- React v18.2.0
- react-dom-router v6.3.0
- styled-components v5.3.5
My intuition tells me that it's something to do with the useLayoutEffect dependency array..
But any suggestions and help on how to fix this bug would be greatly appreciated.
import React, { useRef } from "react";
import { useWindowDimensions } from "../services/hooks/useWindowDimensions";
import { useGetElementDimensions } from "../services/hooks/useElementDimensions";
import {
HeroImage,
HomeContainer,
TextContainer,
TextContainerOverlay,
TextDescription,
} from "../components/StyledElements/HomeStyles.js";
const Home = () => {
const textRef = useRef();
const { width: windowWidth, height: windowHeight } = useWindowDimensions();
const { width:textWidth, height: textHeight } = useGetElementDimensions(textRef)
console.log(textRef);
return (
<HomeContainer height={`${windowHeight - 85}px`}>
<HeroImage
src="https://images.unsplash.com/photo-1587574293340-e0011c4e8ecf?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1932&q=80"
alt="landingImage"
/>
<TextContainer
ref={textRef}
left={`${(windowWidth - textWidth) / 2}px`}
top={`${((windowHeight - textHeight) / 2) - 42}px`}
>
<TextDescription>
Welcome to Pastasauce, a restaurant of italian cuisine focusing
entirely on pasta. On the food selection screen you will be able to
add what you want from the menu and it will be ready for you when you
arrive at the restaurant.
</TextDescription>
<TextContainerOverlay></TextContainerOverlay>
</TextContainer>
</HomeContainer>
);
};
export default Home;
The following is the custom hook, that I'm using for getting the elements dimensions.
import { useCallback, useLayoutEffect, useState } from "react";
export const useGetElementDimensions = (ref) => {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const handleResize = useCallback(() => {
setWidth(ref.current.offsetWidth)
setHeight(ref.current.offsetHeight)
}, [ref]);
useLayoutEffect(() => {
window.addEventListener('load', handleResize);
window.addEventListener('resize', handleResize)
return () => {
window.removeEventListener('load', handleResize)
window.removeEventListener('resize', handleResize)
}
}, [ref, handleResize])
return {width, height}
}
