NextJS:如何在自定义钩子中使用窗口?
2021-02-28
10833
ReferenceError:window 未定义
当 NextJS 尝试呈现页面时,此错误会在服务器端引发。但您可以在
useEffect
钩子中使用
window
,如
此处
所述。
我的问题是如何创建自定义钩子。我尝试过类似这样的操作:
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);
});
};
此处的
window
在
useEffect
中使用。但我收到错误,因为当我调用
useEventListener(window, 'scroll', () => {...});
NextJS 无法识别它。
我该如何处理?
2个回答
我不确定该解决方案是否是最好的,但您可以使用
globalThis
代替
window
,它等同于客户端上的
window
。
Yoskutik
2021-03-01
您仍会收到相同的错误,因为当您调用
useEventListener(window, 'scroll', () => {...});
时,服务器上仍未定义
window
。您应仅在
useEffect
的回调中引用
window
。
例如,如果未定义
target
,则可以将现有的自定义钩子修改为默认为
window
。
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);
});
};
然后,您可以像这样调用钩子:
useEventListener(undefined, 'scroll', () => {...});
您甚至可以从钩子中删除
target
参数,并始终使用
window
,以简化用法和语法。
juliomalves
2021-02-28