I need to grab the height of a div in React using useRef
and assign it to a variable, defaultHeight
.
const jselectRef = useRef<HTMLButtonElement>(null)
let defaultHeight: number | undefined
console.log(defaultHeight) // returns undefined
useEffect(() => {
if (jselectRef.current !== null) {
defaultHeight = jselectRef.current.offsetParent?.clientHeight
console.log(defaultHeight) // returns the height of the div (40)
}
}, [])
console.log(defaultHeight) // returns undefined, even after first page render
Since useEffect
runs after the page is rendered, I need to declare the defaultHeight
variable outside of it, but assign it to the ref inside of it.
However, when I declare the variable outside of useEffect
, then the variable gets reset to undefined every time my component re-renders.
Is there a way to tell React to only declare the variable
let defaultHeight: number | undefined
once, before page load? Then once useEffect
sets the variable based on the ref, leave it alone?
useEffect
doesn't work here, because then the first load will be undefined
, which triggers TypeScript.
I don't think useMemo
would apply here since we are just declaring the variable, but I could be mistaken.
CodePudding user response:
You could use another ref. (This is largely what refs are for--variables that persist across renders--so this seems like the best option to me.)
const defaultHeight = useRef();
useEffect(() => {
// ...
defaultHeight.current = 123;
})
Or use state, but note that this could trigger a re-render, which you may not want.
const [defaultHeight, setDefaultHeight] = useState();
useEffect(() => {
// ...
setDefaultHeight(123);
}, [])
Or you could move it outside the component altogether, but as Giorgi Moniava rightly points out in a comment below, this approach will cause interference if the component is used in multiple places--they'll all update the same variable--and is therefore not recommended. Leaving this option here just to note why you shouldn't do it this way.
let defaultHeight;
function MyComponent () {
useEffect(() => {
// ...
defaultHeight = 123;
});
}