【问题标题】:Gatsby 3rd party scripts not working as intendedGatsby 3rd 方脚本未按预期工作
【发布时间】:2021-06-12 10:14:06
【问题描述】:

在我的 gatsby 项目中包含 fastspring 时遇到了问题。问题如下:我在 html 头中添加了脚本,但它不适用于所有页面(它仅在我刷新页面时才有效) 我试图通过在 html.js 中插入脚本来解决这个问题,使用 gatsby-ssr.js 和 gatsby-browser.js

gatsby-browser.js

我将相同的代码放在 gatsby-ssr.js 中,我也尝试过使用 Helmet,但对我没有任何作用 我希望它可以在所有页面上工作而无需刷新页面,所以如果有人可以帮助我。提前致谢! :)

【问题讨论】:

  • 不要将你的脚本包含在 html 中,最好是从你的顶级 javascript 模块中使用 require()/import 它,比如 src/pages/index.js - Gatsby 在后台使用的 Webpack 将包括将其放入捆绑包中。
  • 抱歉,被AFK了。您是否有任何自定义组件在您网站的所有页面上呈现?例如,我有一个 layout.js 组件,它是所有其他页面的父级。我会尝试在那里导入你的脚本。不过,您最初使用 html.jsdangerouslySetInnerHTML 的方法似乎是更惯用的解决方案。
  • @BorisBurkov fastspring.com/docs/storefronts 这里是关于店面的,实际上这里是关于 fastspring 的所有文档,还有这里是他们向您展示如何将其包含在常规 htm、css 和 js 页面中的视频youtube.com/watch?v=ffRjNM31IXw,希望对你有所帮助
  • 感谢您的链接。我认为尝试不同的方法并直接将 fastspring 与 React 集成可能是有意义的,如此 repo 中所述:github.com/gurschitz/use-fastspring。也许尝试将该 repo 中的组件插入到您的 layout 组件中?此外,还有一组较低级别的 API,您可以直接将其与 React 生命周期钩子一起使用,例如 componentDidMount 或您的自定义事件处理程序:fastspring.com/docs/access-the-library-with-javascript
  • @BorisBurkov 非常感谢您的帮助,我将在今天晚些时候尝试并提供反馈

标签: javascript reactjs gatsby react-helmet


【解决方案1】:

似乎是一个老问题,但有人可能仍然有这个问题。 我确实寻找了一段时间的解决方案,最后我选择了以下方法。

  1. 我创建了一个名为 FastSpringStoreApi.js 的组件。它加载 FastSpring API 并从中订阅 2 个回调事件 - data-popup-closeddata-data-callback。我使用这两个来调度我在我的 FastSpring 提供程序中侦听的自定义 js 事件。这 2 个事件包含商店运作所需的所有信息(商品、定价、购物车信息)

注意:我将数据保存到 sessionStorage 是有原因的。该事件可以在 React 水合物之前被调度。在这种情况下,我将会话存储中的数据作为减速器的初始状态。

import React from 'react';
import {
  FS_EVENTS,
  FS_SESSION_KEY
} from './FastSpringStore.keys';

export default ({ storeFrontId }) => (
  <>
    <script
      type="text/javascript"
      dangerouslySetInnerHTML= {{
        __html:`
          function raiseFSPopupCloseEvent(data) {
            var popupCloseEvent = new CustomEvent(
             '${FS_EVENTS.POPUP_CLOSE}',
             { detail: data }
            );
            window.dispatchEvent(popupCloseEvent);
          }
          
          function raiseFSDataUpdateEvent(data) {
            var dataUpdateEvent = new CustomEvent(
             '${FS_EVENTS.DATA_UPDATE}',
             { detail: data }
            );
            
            window
              .sessionStorage
              .setItem(
                '${FS_SESSION_KEY}',
                 JSON.stringify(data)
               )
              
            window.dispatchEvent(dataUpdateEvent);
          }
        `
      }}
    />
    <script
      id="fsc-api"
      src="https://d1f8f9xcsvx3ha.cloudfront.net/sbl/0.8.5/fastspring-builder.min.js"
      type="text/javascript"
      data-popup-closed="raiseFSPopupCloseEvent"
      data-data-callback="raiseFSDataUpdateEvent"
      data-continuous="true"
      data-storefront={storeFrontId}
    />
  </>
)
  1. 我只在gatsby-ssr.js 中加载这个组件
export const onRenderBody = ({ setHeadComponents }) => {
  setHeadComponents([
    <FastSpringStoreApi
      key="fast-spring-store-api"
      storeFrontId="..."
    />,
  ])
}
  1. 我有 FasSpringStore 提供程序,我在其中订阅我的 fs 事件。看起来像这样。有了它,我可以进一步获取任何组件所需的所有数据。
useEffect(() => {
    const onPopupClosed = (data) => {
      // Popup was closed and order was finished (we have order id)
      if (_has(data.detail, 'id')) {
        // Navigate to home page
        // TODO: Show thank you page in the future
        navigate('/')
        dispatch(cleanShopStore())
      }
    }

    const onDataUpdate = (data) => {
      dispatch(
        setOrderInfo(
          mapFSDataToPayload(
            data.detail
          )
        )
      )
    }

    window.addEventListener(FS_EVENTS.POPUP_CLOSE, onPopupClosed, false);
    window.addEventListener(FS_EVENTS.DATA_UPDATE, onDataUpdate, false);


    return () => {
      window.removeEventListener(FS_EVENTS.POPUP_CLOSE, onPopupClosed)
      window.removeEventListener(FS_EVENTS.DATA_UPDATE, onDataUpdate)
      window.sessionStorage.removeItem(FS_SESSION_KEY)
    }
  }, [])
  1. gatsby-ssr.js 内部,我将根元素与 store provider 一起包装
export const wrapRootElement = ({ element }) => (
  <FastSpringStoreProvider>
    {element}
  </FastSpringStoreProvider>
);
  1. gatsby-browser.js 也是如此
export const wrapRootElement = ({ element }) => (
  <FastSpringStoreProvider>
    {element}
  </FastSpringStoreProvider>
);

希望这能为 FastSpring 的实现提供一些想法。

【讨论】:

    猜你喜欢
    • 2016-09-07
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-20
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多