Yoskutik
Yoskutik

Reputation: 2089

NextJS: how to use window in custom hook?

ReferenceError: window is not defined

This errors raises on the server side, when NextJS tries to render the page. But you can use window in the useEffect hook as written here.

My question is how to create a custom hook. I tried to something like that:

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 here is used in useEffect. But I got the error, because when I call

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

NextJS do not recognize it.

How can I deal with it?

Upvotes: 3

Views: 11053

Answers (2)

Yoskutik
Yoskutik

Reputation: 2089

I'm not sure that solution is the best, but instead of window you can use globalThis which is equal to window on the client side.

Upvotes: 6

juliomalves
juliomalves

Reputation: 50308

You're still getting the same error because window will still not be defined on the server when you call useEventListener(window, 'scroll', () => {...});. You should only reference window when inside the useEffect's callback.

For example, you could modify your existing custom hook to default to window if no target is defined.

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

Then you could call the hook like:

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

You could even remove the target param from the hook and always use window to make the usage and syntax simpler.

Upvotes: 2

Related Questions