如何解决无法使用 React useEffect 并且使用 Gatsby 构建失败
我正在使用 Nacelle、Gatsby 和 Shopify plus 构建一个无头电子商务网站。
我的问题是我集成了 Okendo API 来获取产品评论并且无法构建项目。
实际上,如您所知,无头电子商务对我们来说是一项新技术,但它大多与 Gatsby 和 SSR 接近。
我尝试了两种方法,一种是使用 gatsby-react-helmet 将脚本包含到 head
中,另一种是在 useEffect
或 useLayoutEffect
中调用 window api。
1.包括使用 gatsby-plugin-react-helmet 标记的脚本。
ProductReview.js
import React,{ useEffect } from 'react';
import { Helmet } from 'react-helmet';
import transformProductId from '../../utils/transformProductId';
import { PRODUCT_REVIEW_METAFIELD_KEY,OKENDO_SUBSCRIBER_ID } from '../../constants';
const ProductReview = ({
product
}) => {
const OkendoSettings = {
filtersEnabled: true,omitMicrodata: true,subscriberId: OKENDO_SUBSCRIBER_ID,widgetTemplateId: "default"
}
return (
<>
<Helmet>
<script type="application/javascript" src="../plugins/okendo/index.js" />
<script type="application/json" id="oke-reviews-settings">
{JSON.stringify(OkendoSettings)}
</script>
<script type="application/javascript" src="../plugins/okendo/initAPI.js" />
</Helmet>
<div
data-oke-reviews-widget
data-oke-reviews-product-id={transformProductId(product.id)}
/>
</>
);
};
export default React.memo(ProductReview);
/plugin/okendo/index.js
(function () {
function asyncLoad() {
var urls = ['https:\/\/d3hw6dc1ow8pp2.cloudfront.net\/reviewsWidget.min.js?shop=example.myshopify.com'];
for (var i = 0; i < urls.length; i++) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = urls[i];
var x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s,x);
}
}
if (window.attachEvent) {
window.attachEvent('onload',asyncLoad);
} else {
window.addEventListener('load',asyncLoad,false);
}
})();
/plugin/okendo/initAPI.js
window.okeReviewsWidgetOnInit = function (okeInitApi) {};
如果我将 Okendo 脚本包含到 head 标记中,则一切正常。 但是当我尝试在 vercel 上构建时,它显示“错误为路径 /products/example-product-slug 构建静态 HTML 失败”。
2.在 useEffect 中调用 window.init api。
ProductReview.js
import React,widgetTemplateId: "default"
}
useEffect(() => {
if (typeof window !== `undefined` && window.okendoInitApi) {
const reviewsWidget = window.document.querySelector('#oke-reviews-widget');
window.okendoInitApi.initReviewsWidget(reviewsWidget);
}
},[product.id]);
return (
<>
<Helmet>
<script type="application/javascript" src="../plugins/okendo/index.js" />
<script type="application/json" id="oke-reviews-settings">
{JSON.stringify(OkendoSettings)}
</script>
{/* <script type="application/javascript" src="../plugins/okendo/initAPI.js" /> */}
</Helmet>
<div
id="oke-reviews-widget"
data-oke-reviews-widget
data-oke-reviews-product-id={transformProductId(product.id)}
/>
</>
);
};
export default React.memo(ProductReview);
虽然我使用 useEffect
初始化 Okendo api,但它仅在页面刷新时有效,如果我打开页面则无效。
如果我尝试构建它,它会显示“在服务器端渲染期间错误“窗口”不可用。
我知道除非在浏览器中,否则 useEffect
不会运行,但我仍然不明白解决方案是什么。
希望听到好消息。
谢谢。
更新:产品 ID 是从名为 handle
的 Shopify 产品 graphql 数据生成的。
gatsby-node.js
exports.createPages = async ({ graphql,actions: { createPage } }) => {
// Fetch all products
const products = await graphql(`
{
allNacelleProduct (filter: { availableForSale: {eq: true} }) {
edges {
node {
handle
}
}
}
}
`);
products.data.allNacelleProduct.edges.forEach((product) =>
createPage({
// Build a Product Detail Page (PDP) for each product
path: `/products/${product.node.handle}`,component: path.resolve('./src/templates/product-detail.js'),context: {
handle: product.node.handle
}
})
);
...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。