【问题标题】:Gatsby production build is different from local buildGatsby 生产版本与本地版本不同
【发布时间】:2020-11-24 13:03:11
【问题描述】:

我的生产版本中有一个奇怪的结果,而我的本地开发版本中没有复制。我正在使用 Gatsby 和 ReactBootstrap 来制作标签和轮播。我已经对应用进行了编码,如果屏幕宽度小于 576,则加载轮播组件,否则加载选项卡组件。

所以这就是问题所在。 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;

【问题讨论】:

    标签: reactjs gatsby


    【解决方案1】:

    由于在初始渲染点,您的代码在const width = useWindowWidth(); 处请求windowwidth,因此您的代码仅在第一次加载时工作,因为您的windowwidth 仅设置一次,它被锁定到该值,直到它重新渲染。您的 width 将仅适用于第一次渲染。

    要实现您想要做的事情,您必须首先检查window 的可用性,以便在设置之前等待您的所有逻辑。这将导致几毫秒的闪烁,直到代码计算 windowwidth 并选择渲染的组件,但这是处理任何静态站点生成器和 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 创建来进行计算并根据width 值显示一个或另一个组件,这将取决于window 的可用性。

    您可以在Gatsby's documentation 上查看有关window(和全局对象)的更多信息。

    【讨论】:

    • 这是一个非常彻底的答案。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多