Gatsby构建失败,因为在React挂钩中未定义窗口

时间:2020-05-26 14:03:15

标签: reactjs gatsby

我有一个自定义钩子,该钩子检查窗口宽度以有条件地呈现某些UI元素。在开发过程中可以正常运行,但无法在Gatsby构建上运行。

这是我的钩子的代码:

export const useViewport = () => {
  const [width, setWidth] = React.useState(window.innerWidth);

  React.useEffect(() => {
    const handleWindowResize = () => setWidth(window.innerWidth);
    window.addEventListener("resize", handleWindowResize);
    return () => window.removeEventListener("resize", handleWindowResize);
  }, []);

  // Return the width so we can use it in our components
  return { width };
}

然后在我的组件中按如下方式使用它:

const { width } = useViewport();
const breakpoint = 767

/** in JSX **/

{
  width > breakpoint ? <Menu {...props} /> : <Drawer {...props} />
}

根据盖茨比docs window,在构建过程中不可用。我试图if (typeof window !== 'undefined')限制该挂钩,但是出现以下错误:

Cannot destructure property 'width' of 'Object(...)(.  ..)' as it is undefined

我也曾尝试将const { width } = useViewport()包裹在React.useEffect钩子中,但随后出现一个错误,即我的JSX中的width未定义。

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

看到少量solutions here

特别是这个:

您需要调整挂钩本身。在外部范围内定义默认值并将其用作默认状态应该可以解决问题:

答案 1 :(得分:0)

尝试一下:

      let width;

      if (typeof window !== 'undefined') width= useViewport();

   /** in JSX **/

   {
     width > breakpoint ? <Menu {...props} /> : <Drawer {...props} />
   }

您触犯了这个问题,但是,您在初始渲染点调用了自定义钩子,因此代码崩溃了,因为尚未定义window。使用此代码段,您可以等到定义window来调用该方法。