
react-qr-code 默认渲染 SVG,不支持 toDataURL();需改用 qrcode.react 的 组件,才能调用 Canvas 原生方法实现 PNG 下载。
`react-qr-code` 默认渲染 svg,不支持 `todataurl()`;需改用 `qrcode.react` 的 `
在 React 应用中生成并下载 QR 码时,一个常见误区是误将 SVG 元素当作 Canvas 元素操作。例如,使用 react-qr-code 库时,其默认导出的
✅ 正确解法是切换至支持双渲染模式的库:qrcode.react(注意包名不同,非 react-qr-code)。它提供两个专用组件:
-
:输出可缩放矢量图(适合展示,不支持 toDataURL) -
:输出 元素(支持 toDataURL()、toBlob() 等 Canvas API)
✅ 步骤一:安装并导入正确组件
npm install qrcode.react # 或 yarn add qrcode.react
import { QRCodeCanvas } from 'qrcode.react';✅ 步骤二:使用 渲染,并确保 ID 可选中
return (
<div>
<QRCodeCanvas
id="qrcode"
level="H"
value={box.id}
size={100}
bgColor="#ffffff"
fgColor="#000000"
/>
<Button onClick={downloadQRCode}>Download QR</Button>
</div>
);✅ 步骤三:安全获取 canvas 并触发下载
const downloadQRCode = () => {
const canvas = document.getElementById('qrcode') as HTMLCanvasElement;
if (!canvas) {
throw new Error('QR code canvas element not found. Ensure QRCodeCanvas has the correct id.');
}
// 生成 PNG Data URL(无需 replace MIME type)
const pngUrl = canvas.toDataURL('image/png');
const link = document.createElement('a');
link.href = pngUrl;
link.download = `${box.id}.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};⚠️ 注意事项:
- 不要对 toDataURL() 返回的 URL 执行 .replace("image/png", "image/octet-stream"):现代浏览器已支持直接下载 Data URL,强行修改 MIME 可能导致兼容性问题或失效;
- 若需更高画质,可增大 size 属性(如 size={400}),QRCodeCanvas 会自动缩放渲染;
- SSR(服务端渲染)环境下,
可能因无 DOM 报错,建议配合 useEffect 或动态导入(dynamic(import(...), { ssr: false })); - 如需支持 IE11,请添加 polyfill(toDataURL 在 IE 中仅支持 image/png,且需 canvas 已绘制完成)。
? 进阶提示:若需导出高分辨率或带 Logo 的二维码,推荐结合 html2canvas 或 canvas-toBlob(配合 FileSaver.js)实现更灵活的导出控制。
通过以上调整,即可稳定调用 Canvas API 实现一键 PNG 下载,彻底规避 “toDataURL is not a function” 错误。










