【问题标题】:Using React hooks conditionally in Next JS在 Next JS 中有条件地使用 React 钩子
【发布时间】:2019-05-27 02:19:01
【问题描述】:

编辑:这个问题最初是关于在 CodeSandbox 环境中使用 React 钩子时出现类型错误,但我已经对其进行了更新,以便对未来的访问者有用。

我正在使用以下代码尝试创建一个钩子,以使用滚动位置为网站标题的高度设置动画。问题是我尝试了各种方法来阻止它在服务器上出错,但不断收到各种错误(尽管检查了窗口对象的存在)。

我的原始问题中有一些示例代码,我更新了以下代码沙箱。

https://codesandbox.io/s/p5y6262qzm

原始问题:

未处理的拒绝(TypeError):Object(…) 不是函数

首先我知道这个标题还有其他问题,但似乎有多种原因,我找不到涵盖我的特殊情况的答案。

我可以用来生成示例的最简单(不完整)代码是这样的......

import React, { useState, useEffect } from "react";

const useScrollPosition = () => {
  // Store the state
  const [scrollPos, setScrollPos] = useState(window.pageYOffset);

  return scrollPos;
};

export default useScrollPosition;

虽然有一个更完整的示例说明我在此代码框中尝试做的事情:

https://codesandbox.io/s/p5y6262qzm

我猜这很简单,我似乎无法理解它。

【问题讨论】:

  • 这里的问题是 React 不是最新的。它应该是 16.7 alpha。您可以检查 React.version 是 16.5.2。我希望useState 会导致undefined is not a function,我不能说为什么它会说Object(...)。无论如何,问题在于代码和框 Next.js 模板。
  • 啊,当然。我没有想到,因为我的项目有正确的版本,当我遇到这个时,我正在使用代码沙箱制作一个演示来说明一个未连接的问题。你想把它转换成正确的答案还是你认为我应该删除这个问题?
  • 嗯,实际上这似乎仍然不起作用。我添加了两个不同版本的 alpha ,观看了 NPM 并两次刷新了页面。
  • 考虑更新问题,使其更适合您当前的问题。我试图解决它。

标签: javascript reactjs next.js react-hooks


【解决方案1】:

此 Next.js 设置会导致

TypeError: window.addEventListener 不是函数

客户端出错,因为window global 被局部变量遮蔽:

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 钩子)不是一个好习惯,因此它是一个使用此钩子的组件,需要有条件地呈现。

【讨论】:

  • 再次感谢 Estus,我很确定您的回答是正确的,但我的错是不理解它。您示例中的“w”对象将是“true”或 {width...}。怎么保证服务端使用W对象,客户端使用window对象?听起来很简单,但我在服务器上有条件地做事的每一次尝试都失败了。不幸的是,no-ssr 不是一个选项,因为需要根据滚动位置更改高度的组件是出于 SEO 原因需要存在的站点标题。
  • 我似乎已经通过输入“if (typeof window === "undefined") return 0;”来修复它作为我的钩子函数的第一行。
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 2020-08-11
  • 2020-09-19
  • 1970-01-01
相关资源
最近更新 更多