Home > Enterprise >  Declare variable only once BEFORE render in react?
Declare variable only once BEFORE render in react?

Time:09-22

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;
  });
}
  • Related