在Next JS中有条件地使用React钩子

时间:2018-12-29 18:43:53

标签: javascript reactjs next.js react-hooks

编辑:这个问题最初是关于在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

我猜这真的很简单,我似乎无法将手指放在上面。

1 个答案:

答案 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钩子)的一种好习惯,因此使用该钩子的组件需要有条件地呈现。