I am using react, typescript and tailwind. I want one element's height to match the height of another element. It would be very simple usually but I have a complicated div structure so I can't do it in a normal way. What I have attempted is to calculate the offsetHeight and offsetTopHeight, and set the second element's height this value. The code is below, but I have removed a lot of the other code not related to this to make it easier for y'all to understand.
const [offsetTopHeight, setOffsetTopHeight] = useState(0);
const [offsetHeight, setOffsetHeight] = useState(0);
const [totalHeight, setTotalHeight] = useState(0);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
setTimeout(() => {
if (ref.current != null) {
setTopHeight(ref.current.offsetTop);
setOffHeight(ref.current.offsetHeight);
setTotalHeight(ref.current.offsetTop ref.current.offsetHeight);
console.log(
"total height: ",
ref.current.offsetTop ref.current.offsetHeight
);
console.log("offset height: ", ref.current.offsetHeight);
console.log("offset top: ", ref.current.offsetTop);
}
}, 300);
}, []);
return (
<div id="this-div-copies-height" className={`h-[${totalHeight.toString()}px]`}></div>
<div id="this-div-sets-height" ref={ref}></div>
);
I set a timeout cause I read that it would delay the calculation of the height till after the element rendered. Even without the timeout the code doesn't work though. Offset height finds the height of the element, and offset top height finds the distance between the top of the screen and the top of the element. I have added these to get the distance from the top of the screen to the bottom of the element. Any help would be appreciated, thanks!
CodePudding user response:
as your question title describes "Finding the height of an element and then using that value to set the height of another element" this will do the job :
import React, { useState, useEffect, useRef } from "react";
export default () => {
const [height, setHeight] = useState(0);
const ref = useRef(null);
useEffect(() => {
setHeight(ref.current.clientHeight);
}, [setHeight]);
return (
<div>
<div ref={ref}> element A : {height} </div>
<div style={{ height: { height } }}>
element B has the same Height as element A
</div>
</div>
);
};
full sandbox here
CodePudding user response:
So first thing I would say is it be worth restructuring the divs? I always think using plain CSS to style non dynamic divs is better memory use but do understand there are times when this is necessary so assuming this going forward.
Omar Dieh
's code seems to work nicely (except i think he meant <div style={{ height }}>
instead of <div style={{ height: { height } }}>
). However, I would add that react has a hook called useLayoutEffect
which runs after the dom has loaded allowing for dom manipulation so you can get rid of that timeout with the - what im assuming is - arbitrary number of seconds. Read more here: https://reactjs.org/docs/hooks-reference.html#uselayouteffect