[英]Gatsby: React conditional rendering based on window.innerWidth misbehaving
[英]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,您必须检查浏览器全局变量(如document
或window
)的可用性,因为在您的代码编译并请求这些变量时,它们可能尚未声明/可用。
从盖茨比文档:
您的一些代码引用了“浏览器全局变量”,例如
window
或document
。 如果这是您的问题,您应该会看到上面的错误,例如“未定义窗口”。 要解决此问题,请找到有问题的代码,并且 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.