Производственная сборка Gatsby отличается от локальной сборки - PullRequest
2 голосов
/ 04 августа 2020

У меня странный результат в моей производственной сборке, который не реплицируется в моей локальной разрабатываемой сборке. Я использую Gatsby с React Bootstrap для создания вкладок и карусели. Я закодировал приложение таким образом, что если ширина экрана меньше 576, компонент карусели загружается, в противном случае загружается компонент вкладки.

Итак, вот в чем проблема. Первые два узла HTML в service_carousel. js, то есть теги 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;

и основная служба. 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 Ответ

1 голос
/ 04 августа 2020

Поскольку в начальной точке рендеринга ваш код запрашивает window s width at const width = useWindowWidth();, ваш код будет работать только при первой загрузке, так как width вашего window установлен только один раз, и он будет привязан к этому значению до повторного рендеринга. Ваш width будет применяться только к первому рендерингу.

Чтобы достичь того, что вы пытаетесь сделать, вы должны сначала проверить доступность window, чтобы дождаться всех ваших logi c, прежде чем он будет установлен. Это вызовет мигание на несколько миллисекунд, пока код не вычислит window s width и не выберет, какой компонент рендерить, но это единственный способ сделать с любым генератором сайта c и расчетами 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.

Дополнительную информацию о window (и глобальных объектах) можно найти в документации Gatsby .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...