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

如何解决Flask API返回JSON在React中渲染Plotly图表白屏问题

问题排查结果

你的代码存在4个直接导致图表空白的核心问题:

  • 接口路径不匹配:Flask端定义的接口路由是/chart1,React端fetch请求写的是/plot,根本无法获取到正确的图表配置数据
  • 渲染时机完全错误:Plotly.newPlot直接写在组件函数顶层,执行时存在两个问题:一是目标DOM节点graph-div还未完成挂载,查找不到渲染容器;二是首次执行时plot状态还是初始值0,不是Plotly可解析的合法配置;三是后续接口返回数据更新plot状态后,没有触发任何图表重绘逻辑
  • API传参不符合要求:Flask端通过PlotlyJSONEncoder序列化返回的figure对象结构为{data: [], layout: {}, frames: []},而Plotly.newPlot的标准调用格式为Plotly.newPlot(渲染容器, 数据数组, 布局配置, 其他配置),直接把整个返回对象作为第二个参数传入不符合API参数规则
  • 容器样式问题:未给图表容器设置明确宽高,即使渲染成功也会因为容器高度为0看不到内容
修复方案

1. 可选:Flask端增加跨域支持(前后端分离本地开发时必须配置)

如果本地开发时React运行在3000端口、Flask运行在5000端口,先安装依赖:

pip install flask-cors

修改Flask代码初始化CORS:

from flask import Flask
from flask_cors import CORS
import pandas as pd
import json
import plotly
import plotly.express as px

app = Flask(__name__)
CORS(app) # 允许跨域请求

@app.route('/chart1')
def chart1():
    df = pd.DataFrame({
        "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
        "Amount": [4, 1, 2, 2, 4, 5],
        "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
    })

    fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    return graphJSON

if __name__ == '__main__':
    app.run(debug=True)

2. 重写React端渲染逻辑

修复路径问题、渲染时机问题、传参问题,用ref替代id查找DOM,增加卸载清理逻辑防止内存泄漏:

import React, { useState, useEffect, useRef } from 'react';
import Plotly from 'plotly.js-dist-min';
import logo from './logo.svg';
import './App.css';

function App() {
  // 绑定图表DOM节点,避免全局id查找的冲突问题
  const graphRef = useRef(null);
  // 初始值设为null,区分数据未加载状态
  const [plotConfig, setPlotConfig] = useState(null);

  // 组件挂载时拉取图表数据,修正接口路径为/chart1
  useEffect(() => {
    fetch('/chart1')
      .then(res => {
        if (!res.ok) throw new Error('接口请求失败');
        return res.json();
      })
      .then(data => setPlotConfig(data))
      .catch(err => console.error('图表数据获取失败:', err));
  }, []);

  // 数据加载完成+DOM挂载后再渲染图表
  useEffect(() => {
    if (graphRef.current && plotConfig) {
      // 按Plotly API要求拆分参数传入
      Plotly.newPlot(
        graphRef.current,
        plotConfig.data,
        plotConfig.layout,
        { responsive: true } // 开启自适应
      );
    }

    // 组件卸载时清理图表实例,防止内存泄漏
    return () => {
      if (graphRef.current) Plotly.purge(graphRef.current);
    }
  }, [plotConfig]);

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        {/* 给容器设置明确宽高,绑定ref */}
        <div 
          ref={graphRef} 
          className="graph-div"
          style={{ width: '90%', height: '500px' }}
        ></div>
      </header>
    </div>
  );
}

export default App;

验证步骤

修改完成后:

  1. 启动Flask服务,直接访问对应服务地址的/chart1路径,确认能正常返回包含data、layout字段的JSON数据
  2. 启动React服务,打开浏览器开发者工具的Network面板,确认/chart1接口返回200状态码,无跨域报错
  3. 查看Console面板无Plotly相关参数错误,即可正常渲染分组柱状图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:57:13