Leveraging Window Object in Custom Hooks with NextJS

ReferenceError: window is not defined

This issue arises on the server side when NextJS attempts to render the page. However, it is possible to utilize window within the useEffect hook by following the guidance provided here.

I am seeking advice on creating a custom hook. My attempt looks like this:

export const useEventListener = (
    target: EventTarget, event: string, listener: EventListenerOrEventListenerObject, trigger = true,
): void => {
    useEffect(() => {
        target.addEventListener(event, listener);
        trigger && target.dispatchEvent(new Event(event));
        return () => target.removeEventListener(event, listener);
    });
};

The window reference is utilized in the useEffect. Nonetheless, I encountered an error when using it in this manner:

useEventListener(window, 'scroll', () => {...});

NextJS does not recognize it. What steps can be taken to address this issue?

Answer ā„–1

I'm uncertain about the optimal solution, but you have the option to utilize globalThis instead of window, as it represents the same object on the client side.

Answer ā„–2

The error persists because the window object is still not defined on the server when attempting to use

useEventListener(window, 'scroll', () => {...});
. It is advisable to only reference the window object within the callback of the useEffect.

To address this issue, you can update your custom hook to default to using the window object if no specific target is provided.

export const useEventListener = (
    target: EventTarget, 
    event: string, 
    listener: EventListenerOrEventListenerObject, 
    trigger = true
): void => {
    useEffect(() => {
        const t = target || window
        t.addEventListener(event, listener);
        trigger && t.dispatchEvent(new Event(event));
        return () => t.removeEventListener(event, listener);
    });
};

You can then use the hook as follows:

useEventListener(undefined, 'scroll', () => {...});

If desired, you could simplify the usage and syntax by eliminating the target parameter from the hook and always relying on the window object.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on installing React packages during runtime

My React project has a number of packages that need to be installed, but they take up a lot of disk space. I would like to install them only when necessary, after the user interacts with a specific component that requires these packages. Is there a way t ...

Guide to adding sound effects to your Vue 3 app using the Composition API

I'm having trouble setting up a basic button click feature in Vue 3 Composition API to play a sound effect. In my setup function, I have imported an mp3 sound effect from the assets folder and passed it into a ref method with an HTMLAudioElement type, ...

"When testing with an API client, NextJS 13 successfully returns a response, however, the same response

Having trouble getting a clear answer on something really simple. I've created an API route: // /api/test/route.js export async function GET(request, response) { console.log("requested"); return NextResponse.json({ my: "data" ...

Newbie in JavaScript seeking help with JSON indexing: What could be causing my script using (for ... in) to fail?

Not being a seasoned Javascript coder or very familiar with JSON, my approach may seem naive. Any recommendations for better solutions are appreciated. Below is the code I've written: <!DOCTYPE html> <html> <head> <script& ...

Why do Material UI components fail to render in jsdom while using Jest?

During my UI testing using Jest/React Testing Library, I encountered a peculiar issue. In one of my components, the return statement is structured as follows: const sidebarContentUp = ( <Drawer anchor="left" onClose={onMobileC ...

Verifying if a number is present in a textbox when inserting text (without using setTimeout)

I have an input field similar to the one shown below: <input type ="number" id="numberTxt" placeholder="Number Only"/> To ensure that the value entered is a number, I am using the following function with the keypress event: <script> ...

Troubleshooting: ngAnimate max-height failing to apply to specific element

Having integrated ngAnimate into a project to enhance animations, I've encountered some unusual behavior with a specific element. Let me provide some context: our website features a shop with categories and products within those categories. I am usin ...

Ways to showcase information in a grid column

When looping through a dataset, I am encountering an issue where the display output is in rows instead of columns. <Grid direction="column" container> <Grid xs={6} item> {name} </Grid> </Grid> The current result lo ...

Attempted to register two components under the identical name RTCVideoView in React Native

https://i.stack.imgur.com/un7Mx.jpg Encountering an error while trying to run my app on Android, unsure of the cause or how to resolve it. Despite trying multiple solutions, I haven't been able to fix the issue. Error Message: Tried To register two ...

Establish a connection to Cosmos DB from local code by utilizing the DefaultAzureCredential method

I've created a Typescript script to retrieve items from a Cosmos DB container, utilizing the DefaultAzureCredential for authentication. However, I'm encountering a 403 error indicating insufficient permissions, which is puzzling since I am the ad ...

Enhance Component Reusability in React by Utilizing Typescript

As I embark on developing a React application, my primary goal is to keep my code DRY. This project marks my first experience with Typescript, and I am grappling with the challenge of ensuring reusability in my components where JSX remains consistent acros ...

Performing JSON data extraction and conversion using JavaScript

Hello! I'm working with a script that converts data into an array, but I want to enhance it so that I can extract and convert data for each object (arb, astar, aurora, avax, baba, bsc, etc.), as shown in the screenshot. Here is the current script tha ...

"Encountering an issue with mounting components in React Unit Testing with Jest and Typescript

Having developed a simple app with components, here is the code: import GraphicCanvas from './Graphing/GraphCanvas'; import { drawCircle } from './Graphing/DrawCircle'; function App() { return ( <div className="App"&g ...

What is the reason for next-redux-wrapper double hydrating in the logger?

I am encountering difficulties while using next-redux-wrapper with nextjs and I need some clarification on the concept of Hydrate between server and client. Recently, I have started learning nextjs with next-redux-wrapper and redux-toolkit packages. After ...

Exploring the world of unit testing in aws-cdk using TypeScript

Being a newcomer to aws-cdk, I have recently put together a stack consisting of a kinesis firehose, elastic search, lambda, S3 bucket, and various roles as needed. Now, my next step is to test my code locally. While I found some sample codes, they did not ...

Is there a way for me to adjust the font size across the entire page?

Most CSS classes come with a fixed font-size value already set. For instance: font-size: 16px font-size: 14px etc. Is there a way to increase the font size of the entire page by 110%? For example, font-size: 16px -> 17.6 font-size: 14px -> 15.4 ...

Trouble with using setState within onChange function

Iā€™m on a mission to understand why this method is effective const Navigation:React.FC = () =>{ const [Volume, setVolume] = useState<number>(50) const onChange = (event) => { setVolume(event.target.value); } return( ...

Interested in incorporating dynamic calendar entries in ASP C#?

Here is the code snippet I utilized: <script> var count = 1; var limitValue = 3; function addNewInput(sectionName) { if (count == limitValue) { alert("You have reached the limit of adding " + count + " inputs"); ...

Vue Router configuration functions properly when accessed through URL directly

I need guidance on how to handle the routing setup in this specific scenario: Below is the HTML structure that iterates through categories and items within those categories. The <router-view> is nested inside each category element, so when an item i ...

What is the purpose of using double quotes within single quotes in JavaScript?

Could someone clarify the reason behind needing to nest double quotes inside single quotes in my Webpack configuration shown below? What is preventing using just double quotes? module.exports = merge(prodEnv, { NODE_ENV: '"development"', API ...