javascript - NextJS: hur man använder window i anpassad hook?


ReferenceError: window is not defined

Detta fel uppstår på serversidan när NextJS försöker rendera sidan. Men du kan använda window i useEffect-hooken som skrivet här.

Min fråga är hur man skapar en anpassad hook. Jag försökte med något liknande detta:

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

Fönstret window används här i useEffect. Men jag fick felet, eftersom när jag kallar

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

NextJS känner inte igen det.

Hur kan jag hantera det?

Svar #1

Jag är inte säker på att den lösningen är den bästa, men istället för window kan du använda globalThis vilket är lika med window på klientsidan.

Svar #2

Du får fortfarande samma fel eftersom window fortfarande inte kommer vara definierad på servern när du anropar useEventListener(window, 'scroll',() => {...});. Du bör endast referera till window när du är inne i useEffect:s callback.

Till exempel kan du ändra din befintliga anpassade hook så att den som standard använder window om ingen target är definierad.

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

Då skulle du kunna kalla kroken så här:

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

Du kan till och med ta bort parametern target från hooken och alltid använda window för att göra användningen och syntaxen enklare.

Relaterade artiklar