cssnext.jsuse-effectundefined-behaviorreact-usememo

Window & document not Defined but worked earlier [NextJS]


Earlier this was working and then I rerun using npm run dev and now it's broken again...

I am using tailwindcss as well as useMemo, useEffect and useState.

There are 2 different functions one of them is onMouseMove to create a parallax mouse movement effect the other is to hide the scroll button when scrolling down.

I can't seem to find the answer especially when it was working earlier.

Here's my code:

Index.js

import Image from "next/image";
  import Link from "next/link";
  import { useState, useEffect, useMemo } from "react";
  import { FaDiscord } from "react-icons/fa";    


export default function Home() {
  const [isVisible, setIsVisible] = useState(true);

  useEffect(() => {
    window.addEventListener("scroll", listenToScroll);
    return () => window.removeEventListener("scroll", listenToScroll);
  }, []);

  const root = useMemo(() => document.querySelector(":root"));

  const parallaxHandler = (e) => {
    const x = (e.clientX - window.innerWidth / 2) / 100;
    const y = (e.clientY - window.innerHeight / 2) / 100;
    root.style.setProperty("--posX", -x);
    root.style.setProperty("--posY", -y);
    console.log(x, y);
  };

  const listenToScroll = () => {
    let heightToHideFrom = 150;
    const winScroll =
      document.body.scrollTop || document.documentElement.scrollTop;

    if (winScroll > heightToHideFrom) {
      isVisible && // to limit setting state only the first time
        setIsVisible(false);
    } else {
      setIsVisible(true);
    }
  };

  return (
<>
  {/* HERO */}
  <section
    onMouseMove={parallaxHandler}
    className="w-[100vw] bg-[url(/Home/wave.svg)] bg-orange bg-contain bg-bottom bg-no-repeat parallax   h-[100vh] pt-24 lg:px-0 px-4   lg:pt-0  lg:flex lg:text-left  text-center justify-center  align-middle"
  >
    <div className="self-center xl:mb-20 px-0 lg:px-20  ">
      <h1 className="font-title sm:text-8xl text-5xl ">
        Text
        <br /> <span className="text-black"> Audio </span>
      </h1>
      <h2 className="font-poppins sm:text-2xl text-center lg:text-left  text-xl uppercase py-4">
        With crypto and fiat, coming soon...
      </h2>
      <Link href={"https://discord.com/invite/"} passHref>
        <a target="_blank">
          <button className="flex rounded gap-2 text-md align-middle lg:mx-0 mx-auto bg-grey p-4">
            <FaDiscord
              size="2em"
              color="#FB713A "
              className=" cursor-pointer"
            />
            <p className="my-auto text-orange"> Join our Discord </p>
          </button>
        </a>
      </Link>
    </div>
    <div className="relative  max-h-[60%]  lg:max-h-[100%] w-[471px] h-[549px]  lg:w-[753px] lg:h-[878px] inline-block justify-center xl:flex-col   sm:h-[586px] sm:w-[502px] width object-center">
      <Image
        alt="app_bg"
        className="app_bg"
        src={"/Home/hero_app.png"}
        quality={100}
        layout="fill"
        objectFit="contain"
        priority
      />
    </div>
    {isVisible && (
      <Link href="#whatis">
        <div className="cursor-pointer text-center absolute bottom-0 p-0 left-[40%] right-[40%]">
          <div className="scroll__down">
            <span className="scroll__mouse">
              <span className="scroll__wheel"></span>
            </span>
          </div>
          <p className="text-orange text-xs font-semibold animate-pulse">
            SCROLL TO EXPLORE{" "}
          </p>
        </div>
      </Link>
    )}
    </section>
</>
     );
    }

Styles.css

:root {
  --posX: 0;
  --posY: 0;
}

.parallax .app_bg {
  transform: translate(calc(var(--posX) * 1px), (calc(var(--posY) * 1px)));
}

ERROR MESSAGE

 17 |   }, []);
  18 | 
> 19 |   const root = useMemo(() => document.querySelector(":root"));
     |                                      ^
  20 | 
  21 |   const parallaxHandler = (e) => {
  22 |     const x = (e.clientX - window.innerWidth / 2) / 100;

Solution

  • useMemo wouldn't work for some reason so to solve this I added the variable into the function:

        const parallaxHandler = (e) => {
        let root = document.querySelector(":root");
        const x = (e.clientX - window.innerWidth / 2) / 200;
        const y = (e.clientY - window.innerHeight / 2) / 200;
        root.style.setProperty("--posX", -x);
        root.style.setProperty("--posY", -y);
        console.log(x, y);
      };