在 Next.js 中实现 Cloudinary 产品库

Posted

技术标签:

【中文标题】在 Next.js 中实现 Cloudinary 产品库【英文标题】:Implementing Cloudinary Product Gallery in Next.js 【发布时间】:2021-08-09 06:42:25 【问题描述】:

我正在尝试在我的电子商务 - Next.js 项目中使用 Cloudinary 产品库,但很难将其组合在一起。

这里是 Cloudinary 产品库:https://cloudinary.com/documentation/product_gallery

我得到的错误: Cannot read property 'galleryWidget' of undefined。让我知道我做错了什么。

文件 - _document.js

import Document,  html, Head, Main, NextScript  from 'next/document';

class MyDocument extends Document 
  render() 
    return (
      <Html>
        <Head />
        <body>
          <script
            src="https://product-gallery.cloudinary.com/all.js"
            type="text/javascript"
          ></script>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  


export default MyDocument;

文件 - SingleProduct.jsx

import React,  useRef  from 'react';

const SingleProduct = ( product ) => 
  const  slug  = product;
  const cloudnaryGalleryRef = useRef(null);

  if (!cloudnaryGalleryRef.current) 
    cloudnaryGalleryRef.current = window.cloudinary
      .galleryWidget(
        container: '#my-gallery',
        cloudName: 'cloudName',
        carouselStyle: 'thumbnails',
        thumbnailProps: 
          width: 75,
          height: 75,
          spacing: 4,
          navigationColor: 'green',
        ,
        mediaAssets: [ tag: slug ],
      )
      .render();
  

  return <div id="my-gallery"></div>;
;

export default SingleProduct;

【问题讨论】:

【参考方案1】:

假设你的脚本没有问题,你需要在执行函数之前检查窗口是否可用..

例如

if (typeof window !== 'undefined') 
    ..... window.cloudinary.galleryWidget(.....)

您会注意到这在 nextjs 应用程序中会非常频繁地发生,并且您需要包括这些必要的检查,因为 next.js 在大多数情况下是服务器端生成的,并且在页面加载到浏览器之前,window 没有定义。

【讨论】:

【参考方案2】:

这是一个可行的解决方案

import React,  useRef  from 'react';
const SingleProduct = ( product ) => 
  const  slug  = product;
  const [loaded, setLoaded] = useState(false);

  useEffect(() => 
    const scriptTag = document.createElement('script');
    scriptTag.src = 'https://product-gallery.cloudinary.com/all.js';
    scriptTag.addEventListener('load', () => setLoaded(true));
    document.body.appendChild(scriptTag);
  , []);

  const cloudnaryGalleryRef = useRef(null);

  useEffect(() => 
    if (!loaded) return;
    const myGallery = window.cloudinary.galleryWidget(
      container: '#my-gallery',
      cloudName: 'dhvi46rif',
      carouselStyle: 'thumbnails', // default value: included for clarity
      thumbnailProps: 
        width: 75,
        height: 75,
        spacing: 4,
        navigationColor: 'green',
      ,
      mediaAssets: [ tag: slug ],
    );
    if (!cloudnaryGalleryRef.current && typeof window !== 'undefined') 
      cloudnaryGalleryRef.current = myGallery.render();
    
    return () => 
      cloudnaryGalleryRef.current = myGallery.destroy(); // Important To avoid memory leaks and performance issues, make sure to use the destroy method before removing the Product Gallery widget container element from your DOM.
    ;
  , [loaded, slug]);

  return <div id="my-gallery" />;
;

export default SingleProduct;

【讨论】:

以上是关于在 Next.js 中实现 Cloudinary 产品库的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Next.js 中实现加载屏幕

如何在 Next.js 中实现身份验证

Next.js Cloudinary 图像未使用加载程序显示

Next.js 图像组件不显示 Cloudinary 图像

在 React 中使用 Cloudinary 小部件

如何将图像从 android 上传到 Cloudinary?