如何在Next.js项目中适配使用react-to-print打印功能库
两种组件写法的核心差异
react-to-print的content参数要求返回可访问的真实DOM节点,两种写法的核心区别在于对ref的支持逻辑:
- 类组件存在实体实例,直接给类组件绑定ref可以拿到组件实例,react-to-print可以从实例中读取到渲染生成的真实DOM节点,所以功能可以正常运行
- 普通未处理的函数式组件默认不支持ref绑定,直接给函数式组件加ref属性时,React会抛出非法属性警告,且无法返回任何有效DOM节点,react-to-print获取不到目标打印内容就会无响应
- 你修改导入语句只是适配了类组件的命名导出规则,不是功能恢复的核心原因,核心触发因素是类组件对ref的原生支持
Next.js中正确适配react-to-print的方案
1. 类组件方案(你已实现的可运行方案)
注意两个优化点即可:
- Next.js 13+ App Router场景下,所有用到react-to-print的页面/组件都需要在文件顶部添加
'use client'指令,标记为客户端组件才能正常使用ref、交互事件等浏览器端能力 - 不要将ref挂载到
React全局对象上,建议用useRef存储,避免污染全局变量,参考代码如下:
'use client' import { useRef } from 'react' import ReactToPrint from 'react-to-print' import { PrintComponent } from './PrintComponent' const Index = () => { const printRef = useRef(null) return ( <> <ReactToPrint trigger={() => <button>Print this out!</button>} content={() => printRef.current} /> <div className="hidden"> <PrintComponent ref={printRef} /> </div> </> ); }; export default Index;
2. 函数式组件兼容方案
如果要保留函数式组件写法,需要用forwardRef将ref转发到组件内部的根DOM节点上,参考代码如下:
// PrintComponent.tsx import { forwardRef } from 'react' const PrintComponent = forwardRef((props, ref) => { return ( <div ref={ref}> <p>Count is: 1</p> </div> ) }) export default PrintComponent
该写法下使用默认导入即可正常运行,无需改为类组件。
内容的提问来源于stack exchange,提问作者new dev
相关产品推荐
相关产品推荐

