You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js动态导入react-component-export-image遇函数未定义问题如何处理

问题原因&解决方法

报错根因

  • 第一个window is not defined报错:react-component-export-image依赖浏览器全局对象window和DOM API,Next.js服务端渲染阶段没有对应的浏览器环境,直接导入就会触发报错。
  • 第二个exportComponentAsPNG is not a function报错:next/dynamic是专门用来动态导入React组件的能力,不支持导入普通工具函数,你通过该方法解构出来的内容自然不是可调用的方法。

正确实现方案

方案1:客户端侧动态导入(优先推荐)

不需要使用next/dynamic,直接在仅客户端执行的逻辑中导入库即可,实现代码如下:

import React, { useRef, useState, useEffect } from 'react'
import ProductCard from '../ProductCard/ProductCard.component'

const Plaque = () => {
  const componentRef = useRef()
  const [exportComponentAsPNG, setExportComponentAsPNG] = useState(null)

  // useEffect仅在客户端执行,此处导入不会触发服务端报错
  useEffect(() => {
    import('react-component-export-image').then(module => {
      setExportComponentAsPNG(() => module.exportComponentAsPNG)
    })
  }, [])

  const handleExport = () => {
    // 库未加载完成时不执行逻辑,可自行补充加载中提示
    if (!exportComponentAsPNG) return
    exportComponentAsPNG(componentRef)
  }

  const ComponentToPrint = React.forwardRef((props, ref) => {
    return (
      <div ref={ref}>
        <ProductCard />
      </div>
    )
  })

  return (
    <>
      <ComponentToPrint ref={componentRef} />
      <button onClick={handleExport} disabled={!exportComponentAsPNG}>
        {exportComponentAsPNG ? 'Export As PNG' : '加载中...'}
      </button>
    </>
  )
}

export default Plaque

方案2:抽离客户端组件用next/dynamic导入

如果需要拆分逻辑,可将用到该库的组件单独抽离为客户端组件,再用next/dynamic整体导入:

  1. 新建单独的客户端组件文件PlaqueClient.js:
import React, { useRef } from 'react'
import { exportComponentAsPNG } from 'react-component-export-image'
import ProductCard from '../ProductCard/ProductCard.component'

const PlaqueClient = () => {
  const componentRef = useRef()
  const ComponentToPrint = React.forwardRef((props, ref) => {
    return (
      <div ref={ref}>
        <ProductCard />
      </div>
    )
  })
  return (
    <>
      <ComponentToPrint ref={componentRef} />
      <button onClick={() => exportComponentAsPNG(componentRef)}>
        Export As PNG
      </button>
    </>
  )
}

export default PlaqueClient
  1. 在页面/父组件中动态导入该组件,关闭服务端渲染:
import dynamic from 'next/dynamic'
// 整体导入客户端组件,不会触发服务端执行
const PlaqueClient = dynamic(() => import('./PlaqueClient'), { ssr: false })

// 业务代码中直接使用<PlaqueClient />即可

替代库推荐

如果该库不符合你的使用需求,可以选择以下同功能的成熟npm库实现React组件转图片的能力:

  • html2canvas:生态最成熟的DOM转Canvas能力库,自定义配置项多,兼容性好,是绝大多数同类工具的底层依赖
  • react-html2canvas:针对React场景封装的html2canvas组件,使用成本更低
  • dom-to-image:比html2canvas更轻量,部分CSS特性的渲染精度更高,同样仅支持客户端执行,导入时需要避开服务端逻辑

内容的提问来源于stack exchange,提问作者Cole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:24:02