繁体   English   中英

如何在网站呈现之前在 React/Gatsby 中检查 window.innerWidth?

[英]How to check window.innerWidth in React/Gatsby before the website will render?

在我在 Gatsby 创建的网站上,我想在第一次渲染之前检查 DOM window.innerWidth 的大小。 我想使用 innerWidth 的条件检查来决定网站应该如何呈现:作为桌面版或移动版。 一个简单的解决方法是在创建反应组件之前检查 window 的宽度,并在代码中进一步使用真/假值。 它在开发版本中工作,但是......情况是,在生产版本中,当我执行gatsby build时,我在控制台中收到错误:

failed Building static HTML for pages - 2.872s

 ERROR #95312 

"window" is not available during server-side rendering.

See our docs page for more info on this error: https://gatsby.dev/debug-html

> 30 |     const sizeOfWindow = window.innerWidth;

我已经尝试使用componentWillMount ,它工作正常,但它已被弃用并标记为不安全。 如果我检查 componentDidMount 中的 window.innerWidth 没有正确呈现。

我的代码:

interface IndexPageState {
  isDesktop: boolean;
  windowWidth: number;
}

class IndexPage extends React.Component<any, IndexPageState> {
  constructor(props: any) {
    super(props);

    this.state = {
      windowWidth: 0,
      isDesktop: true,
    };
  }

  componentWillMount(): void {
    this.onResize();
  }

  onResize = () => {
    if (!(this.state.windowWidth >= 769)) {
      this.setState({ isDesktop: false });
    } else {
      this.setState({ isDesktop: true });
    }
  };

  componentDidMount = () => {
    this.setState({ windowWidth: window.innerWidth });
    if (!(this.state.windowWidth >= 769)) {
      this.setState({ isDesktop: false });
    } else {
      this.setState({ isDesktop: true });
    }
    window.addEventListener('resize', this.onResize);
  };

  componentWillUnmount = () => {
    window.removeEventListener('resize', this.onResize);
  };

  render() {
    const { isDesktop, windowWidth } = this.state;

    return (
      <>
        <SEO title="Home" />
        <div className={styles.App}>

您可以在回调中包装获取 window 宽度,因此添加 function getWindowWidth ,您将在其中返回实际的 window 宽度。

检查window是否以这种方式首先定义后,尝试执行window.innerWidth

componentDidMount() {
    if (typeof window !== 'undefined') {
        window.addEventListener('resize', this.onResize)
    }
}
componentWillUnmount() {
    if (typeof window !== 'undefined') {
        window.removeEventListener('resize', this.onResize)
    }
}

使用 Gatsby,您必须检查浏览器全局变量(如documentwindow )的可用性,因为在您的代码编译并请求这些变量时,它们可能尚未声明/可用。

盖茨比文档

您的一些代码引用了“浏览器全局变量”,例如windowdocument 如果这是您的问题,您应该会看到上面的错误,例如“未定义窗口”。 要解决此问题,请找到有问题的代码,并且 a) 在调用代码之前检查是否定义了 window,因此代码在 Gatsby 构建时不会运行(请参见下面的代码示例)或 b) 如果代码在渲染 function 中一个 React.js 组件,将该代码移动到componentDidMount生命周期useEffect钩子中,以确保代码不会运行,除非它在浏览器中

因此,每次检查window时,都必须添加:

    if(typeof window !== undefined){
     //your stuff
    }

应用于您的代码:

  componentDidMount = () => {
    if(typeof window !== undefined){
      this.setState({ windowWidth: window.innerWidth });
      if (!(this.state.windowWidth >= 769)) {
        this.setState({ isDesktop: false });
      } else {
        this.setState({ isDesktop: true });
      }
      window.addEventListener('resize', this.onResize);
    }
  };


  componentWillUnmount = () => {
    if(typeof window !== undefined){
      window.removeEventListener('resize', this.onResize);
    }

   onResize = () => {
    if(typeof window !== undefined){ 
       if (!(this.state.windowWidth >= 769)) {
         this.setState({ isDesktop: false });
       } else {
       this.setState({ isDesktop: true });
       }
     }
   };
};

当然,上面的代码应该重构以避免条件的重复,例如在事件触发之前添加window条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM