我的生产版本中有一个奇怪的结果,但在本地开发版本中没有复制。我正在将Gatsby与ReactBootstrap结合使用来制作标签和轮播。我已经对该应用程序进行了编码,以便如果屏幕宽度小于576,则将加载轮播组件,否则,将加载Tab组件。
这就是问题所在。 service_carousel.js中的前两个HTML节点(即Container和Carousel标签)在页面加载时添加,并成为service_tabs.js代码的包装器。我不知道为什么由于我是从笔记本电脑的屏幕上查看代码,因此应该加载services_tabs.js代码,并且应该只包含services_tabs.js中指定的节点。如果我检查代码并将设备更改为手机,即使我切换回大屏幕,也将修复错误并删除标签。但是,如果您重新加载页面,则错误会再次出现。
这是一个包含完整代码https://codesandbox.io/s/sad-glade-u8j9g的代码沙箱
我的代码如下:
service_tabs.js
import React from 'react';
import styles from './service_tabs.module.scss';
import { TabContent } from '../component_barrel';
import {
Tab,
Tabs,
Row,
Col,
} from '../../utils/bootstrap_imports_barrel';
import useData from '../../utils/useData';
const tab_data = useData.tab_data;
const ServiceTabs = () => (
<Row className="justify-content-center p-4">
<Col lg={10} md={9} className="align-self-center">
<Tabs justify className={styles.custom_tabs} defaultActiveKey="item 1" id="uncontrolled-tab-example">
{
tab_data.map(({ tab_title, title, icon, image, content }, index) => {
const key = `item ${index + 1}`;
return (
<Tab eventKey={key} key={key} title={tab_title}>
<TabContent
icon={icon}
image={image}
title={title}
content={content}
/>
</Tab>
)
})
}
</Tabs>
</Col>
</Row>
);
export default ServiceTabs;
service_carousel.js
import React from 'react';
import {
Container,
Carousel,
} from '../../utils/bootstrap_imports_barrel';
import styles from './service_carousel.module.scss';
import { TabContent } from '../component_barrel';
import useData from '../../utils/useData';
const tab_data = useData.tab_data;
const ServiceCarousel = () => (
<Container className="p-0" fluid>
<Carousel className="py-4" controls={false} indicators={false} touch={true}>
{
tab_data.map(({ title, icon, image, content }, index) => {
const key = `item ${index + 1}`;
return (
<Carousel.Item key={key} className={styles.carousel_container}>
<TabContent
icon={icon}
image={image}
title={title}
content={content}
/>
</Carousel.Item>
)
})
}
</Carousel>
</Container>
);
export default ServiceCarousel;
和主要service.js
import React from 'react';
import {
ServiceTabs,
ServiceCarousel
} from './component_barrel'
import { useWindowWidth } from '@react-hook/window-size';
const Service = () => {
const width = useWindowWidth();
const componentLoaded = width > 576 ? <ServiceTabs /> : <ServiceCarousel />;
return (
<div className="service_container">
{componentLoaded}
</div>
);
};
export default Service;
答案 0 :(得分:1)
由于在初始渲染点,您的代码要求在window
处使用width
的{{1}},所以您的代码仅在const width = useWindowWidth();
以来的首次加载中起作用width
中的设置仅被设置一次,并且被锁定为该值,直到重新渲染为止。您的window
仅适用于第一个渲染。
要实现您要执行的操作,必须先检查width
的可用性,然后等待所有逻辑设置完毕。这将导致几毫秒的闪烁,直到代码计算出window
的{{1}}并选择要渲染的组件,但这是处理任何静态网站生成器和window
的唯一方法。因此,在您的width
中:
window
请注意,service.js
的重复性应进行重构以避免重复,但作为一种初始方法,它将可以完成工作。此外,就可读性而言,链式三元条件不是最佳选择,但目前仍可以使用。
基本上,您正在等待创建import React from 'react';
import {
ServiceTabs,
ServiceCarousel
} from './component_barrel'
import { useWindowWidth } from '@react-hook/window-size';
const Service = () => {
let width;
if (typeof window !== 'undefined') width = useWindowWidth();
const width = useWindowWidth();
const componentLoaded = typeof window !== 'undefined' ? width > 576 ? <ServiceTabs /> : <ServiceCarousel /> : null;
return (
<div className="service_container">
{componentLoaded}
</div>
);
};
export default Service;
进行计算并显示基于typeof window !== 'undefined'
值的组件或其他组件,该组件将以window
的可用性为条件。
您可以在Gatsby's documentation上查看有关width
(和全局对象)的更多信息。