I tried to access the dom to get the height of a specific element in react using useRef() hook, and assign the height of another element to it, so its height would change dynamically based on the height change of the reference element and I used the height.current.clientHeight property but I encountered an error message saying:
TypeError: Cannot read properties of null (reading 'clientHeight')
and here is the code:
import React from "react";
import Link from "next/link";
import MenuIcon from "./MenuIcon";
import { useState } from "react";
import Image from "next/image";
import bg from "../public/bg.jpg";
import { useRef } from "react";
const Navbar = () => {
const height = useRef(null);
const [open, setOpen] = useState(false);
function handleClick() {
setOpen(!open);
}
return (
<>
<MenuIcon bgC="bg-white" handle={handleClick} open={open} />
<div className="w-full relative h-[40%]" ref={height}>
<nav className="xs:max-md:hidden flex z-20 justify-between md:max-lg:justify-end md:max-lg:gap-24 text-white bg-transparent backdrop-blur-lg py-3 px-6 ">
<div className="hover:text-gray-300 hover:text-[20px] ease-in duration-100">
<Link href="/">About me</Link>
</div>
<div className="hover:text-gray-300 hover:text-[20px] ease-in duration-100">
<Link href="/">My skills</Link>
</div>
<div className="hover:text-gray-300 hover:text-[20px] ease-in duration-100">
<Link href="/">Portfolio</Link>
</div>
<div className="hover:text-gray-300 hover:text-[20px] ease-in duration-100">
<Link href="/">Contacts</Link>
</div>
</nav>
<Image
src={bg}
layout="responsive"
objectFit="contain"
width={400}
height={400}
alt="/"
/>
<div className="w-full h-full bg-black/40 absolute top-0 lef-0 right-0">
<h1 className="text-white w-[75%] font-Neo font-[12px] box-border text-2xl mx-auto text-center translate-y-[140px]">
Hi there! My name is Alharith and I am a front-end developer.
</h1>
</div>
</div>
<div
className={
open
? `w-auto h-${height.current.clientHeight} box-border px-12 bg-blue-400 backdrop-blur-sm fixed top-0 right-0 translate-x-0 duration-300 ease-in flex flex-col items-center justify-around text-2xl`
: `w-auto h-${height.current.clientHeight} px-12 py-[30px] bg-transparent backdrop-blur-sm fixed top-0 right-0 translate-x-[100%] duration-300 ease-in flex flex-col items-center justify-around text-2xl`
}
>
<div className="w-full flex flex-col justify-around items-center h-[50%] gap-8 text-2xl font-Neo">
<div className="font-Neo text-2xl hover:text-[20px] hover:text-gray-100 duration-100 ease-in">
<Link href="/">About me</Link>
</div>
<div className="font-Neo text-2xl hover:text-[20px] hover:text-gray-100 duration-100 ease-in">
<Link href="/">My Skills</Link>
</div>
<div className="font-Neo text-2xl hover:text-[20px] hover:text-gray-100 duration-100 ease-in">
<Link href="/">Portfolio</Link>
</div>
<div className="font-Neo text-2xl hover:text-[20px] hover:text-gray-100 duration-100 ease-in">
<Link href="/">Contacts</Link>
</div>
</div>
</div>
</>
);
};
export default Navbar;
I tried checking if the "height.current !== null" and if true would assign the value of the clientHeight to another variable, if not would assign "auto" as so:
const hi = height.current ? ${height.current.clientHeight}
: "auto"
still getting the same error
I expected it to work fine but it really didn't
The useRef
hook variable doesn't get the current
property immediately. This gets populated after the initial DOM render.
To get this working, add a useEffect
hook with height.current
in dependency array.
And use a flag with useState
hook and inside useEffect
hook, update the flag.
const [flag, setFlag] = useState(false);
useEffect(() => {
if(height.current) setFlag(true);
}, [height.current]);
// and use the flag in div class
<div
className={ open && flag ? `w-auto h-${height.current.clientHeight}...` }
>
//
</div>
For more info, refer this answer