Как я могу добавить скрипт на страницу gatsby, который запускается при каждой загрузке страницы? - PullRequest
1 голос
/ 06 августа 2020

Я пытаюсь добавить собственный сценарий каменной кладки на одну страницу в Gatsby. Он вносит изменения в свойства стиля <div> элементов в макете сетки, но, по сути, скрипт должен делать свое дело каждый раз при загрузке страницы или изменении ее размера.

Способ, которым я пытаюсь достичь sh это через требование скрипта в хуке эффекта в функции, возвращающей компонент React:

// in 'page.js'
export default () => {
    useEffect(() => {
        require('./scripts/masonry');
    }

    return // blah blah blah...
}

И в скрипте я поместил все, что мне нужно, чтобы скрипт делал в функцию вызвал resizeAll, прикрепил его к window.onloadend и добавил в прослушиватель событий изменения размера:

// in the masonry script at the very bottom
window.onloadend = resizeAll;
window.addEventListener('resize', resizeAll);

Но это не работает, потому что скрипт запускается только при изменении размера страницы, но не при загрузке или переходе на страницу. Я подозреваю, что window.onloadend по какой-то причине сломан или заблокирован функциональностью gatsby, или что я использую его неправильно. Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

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

Вы можете сделать это, используя React Helmet , который в основном записывает данные в ваш тег html pages <head>. Также вам понадобится Gatsby's withPrefix для определения пути к скрипту, который встроен в Gatsby.

Скорее всего, у стартера Gatsby, который вы используете, уже установлен React Helmet (см. на ваш package.json). Если это так, просто поместите свой скрипт в папку /static/ вашего проекта, а затем в React включите скрипт в <head> своей страницы следующим образом:

import Helmet from "react-helmet";
import { withPrefix } from "gatsby";

<Helmet>
<script src={withPrefix('masonry.js')} />
</Helmet>

Если по какой-то причине ваш В проекте Gatsby еще нет настройки React Helmet, вы можете настроить, следуя инструкциям здесь .

0 голосов
/ 22 августа 2020

Оказывается, я решил проблему! Хуки, похоже, не помогли, поэтому я вставил функцию resizeAll в экспорт onRouteUpdate в gatsby-browser.

Как сказал Ферран Буйре, это обходной путь, но мой сайт довольно маленький и до сих пор я не заметил серьезного ухудшения производительности, но я перестрою скрипт позже, если понадобится ...

0 голосов
/ 07 августа 2020

Самый простой и чистый способ - использовать gatsby-browser.js. Gatsby предоставляет там несколько API, onClientEntry соответствует вашим требованиям. Из документации:

onClientEntry Функция

(_: emptyArg, pluginOptions: pluginOptions) => undefined

Вызывается при первом запуске среды выполнения браузера Gatsby.

Итак, адаптированный к вашему коду, в вашем gatsby-browser.js просто добавьте:

export const onClientEntry = () => {
    useEffect(() => {
        require('./scripts/masonry');
    }, [])
};

Приведенный выше код предполагает:

  • Скрипт масонства принадлежит вашему собственному проекту.
  • Кладка будет добавлена ​​на все страницы. Если вы не хотите добавлять его на весь сайт. См. Реализацию ниже.

Если вышеперечисленное не работает должным образом или вам не нужно везде. Я бы попытался добавить пустой deps ([]) к исходному хуку useEffect, поскольку это ближайший обходной путь к жизненному циклу componentDidMount:

useEffect(() => {
    require('./scripts/masonry');
}, [])

Если скрипт внешний (сторонний):

useEffect(() => { 
  const script = document.createElement('script') 
  script.async = true script.defer = true 
  script.src = 'https://your_script.com' 
  document.querySelector('ANY_UNIQUE_DIV').appendChild(script) 
}, [])

Приведенный выше код - это всего лишь начальный обходной путь, следует избегать использования document и других переменных DOM в любом приложении React, поскольку они сильно влияют на производительность браузера, вы можете сделать то же самое с крючком useRef.

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