Gatsby生产版本与本地版本不同

时间:2020-08-04 12:21:24

标签: reactjs gatsby

我的生产版本中有一个奇怪的结果,但在本地开发版本中没有复制。我正在将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;

1 个答案:

答案 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(和全局对象)的更多信息。