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整体导入:
- 新建单独的客户端组件文件
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
- 在页面/父组件中动态导入该组件,关闭服务端渲染:
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
相关产品推荐
相关产品推荐

