React中调用Plotly.toImage()获取图片URL返回Promise无法渲染img
问题根因
所有被async标记的函数返回值都是Promise对象,你在同步执行的render方法里直接调用getImage,拿到的是还没完成异步解析的Promise对象,不是最终的图片地址,img标签无法识别Promise作为src值,自然加载失败。另外React的render阶段是纯同步执行的,不支持等待异步操作结果,直接在render里跑异步逻辑本身就不符合React的渲染规则,会引发重复渲染、值不更新等问题。
修复步骤
- 给组件增加状态存储生成的图片地址,初始值可设为空字符串或者加载占位图地址
- 在组件挂载完成、Plotly图表渲染就绪的生命周期钩子中调用图片生成方法,拿到结果后更新组件状态
- render阶段直接从状态中读取图片地址赋值给img的src属性,不要在render内直接调用异步方法
- 注意
Plotly.toImage需要接收正确的图表DOM节点或者已渲染完成的图表容器id,确保导出时图表已经完成渲染
修复后可直接运行的代码
import React, { Component } from 'react'; import Plotly from 'plotly.js'; // 按你项目实际的Plotly引入方式调整即可 class Export extends Component { constructor(props) { super(props); // 初始化状态存储生成的图片地址 this.state = { imgUrl: '' }; } async getImage(div) { const url = await Plotly.toImage(div, {format: 'svg'}); return url; } // 等组件挂载、Plotly图表渲染完成后再生成导出图 async componentDidMount() { // 若你是用ref绑定图表容器,直接传入DOM节点比传id字符串更稳妥 const url = await this.getImage('main'); this.setState({ imgUrl: url }); } render() { return ( <div className='input-container'> {this.state.imgUrl ? ( <img src={this.state.imgUrl} alt='Export preview' width={450} height={300} /> ) : ( <span>图片生成中...</span> )} </div> ) } } export default Export;
额外说明
如果你的Plotly图表是动态更新的,需要在图表每次更新完成后重新调用getImage方法更新state里的imgUrl,否则预览图会停留在旧版本。如果用React Hooks写法逻辑一致,用useState存url,useEffect里执行异步生成逻辑即可。
内容的提问来源于stack exchange,提问作者Bialson
相关产品推荐
相关产品推荐

