编辑:这个问题最初是关于在CodeSandbox环境中使用React钩子时出现类型错误的,但是我已经对其进行了更新,以便对将来的访问者有用。
我正在使用以下代码来尝试创建一个钩子,以使用滚动位置来动画化网站标题的高度。麻烦的是,我尝试了各种方法来使其停止服务器上的错误,但不断出现各种错误(尽管检查window对象是否存在)。
最初的问题中有一些示例代码,并且我更新了以下代码沙箱。
https://codesandbox.io/s/p5y6262qzm
原始问题:
未处理的拒绝(TypeError):对象(...)不是函数
首先,我知道这个标题还有其他问题,但似乎有多种原因,我找不到适合我特殊情况的答案。
我可以用来生成示例的最简单(不完整)的代码是这个...
import React, { useState, useEffect } from "react";
const useScrollPosition = () => {
// Store the state
const [scrollPos, setScrollPos] = useState(window.pageYOffset);
return scrollPos;
};
export default useScrollPosition;
尽管在此codeandbox中有一个我想做的事情的完整示例:
https://codesandbox.io/s/p5y6262qzm
我猜这真的很简单,我似乎无法将手指放在上面。
答案 0 :(得分:2)
此Next.js设置会导致
TypeError:window.addEventListener不是函数
客户端错误,因为全局变量window
被局部变量所遮盖:
const window = window || {
width: 0,
height: 0,
pageXOffset: 0,
pageYOffset: 0
};
应该是:
const w = (typeof window !== 'undefined' && window) || {
width: 0,
height: 0,
pageXOffset: 0,
pageYOffset: 0
};
这将导致在服务器端渲染期间使用模拟对象,而在客户端渲染期间使用window
。
更好的解决方案是避免使用特定于客户端的组件,例如与react-no-ssr
。由于不是有条件地应用钩子(useScrollPosition
钩子)的一种好习惯,因此使用该钩子的组件需要有条件地呈现。