You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React中如何渲染useEffect返回的数据?附代码示例

解决React中渲染Cube.js查询数据的问题

看起来你已经成功通过fetch获取到了Cube API返回的数据,但还没把这些数据和你的图表组件关联起来。我帮你梳理下怎么修改代码,把拿到的数据渲染出来:

步骤1:添加状态管理存储查询数据

首先,你需要用React的useState来存储fetch回来的数据,让组件能感知到数据变化并触发重新渲染:

import { useState, useEffect, useMemo } from 'react';

const ChartRenderer = ({ vizState }) => {
  // 新增状态存储查询结果、加载状态和错误信息
  const [chartData, setChartData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  let ur = encodeURIComponent(JSON.stringify(vizState.query));
  let u = "http://localhost:4000/cubejs-api/v1/sql?query=" + ur;
  console.log(u)

  useEffect(() => {
    // 过滤空查询请求
    if(u === "http://localhost:4000/cubejs-api/v1/sql?query=undefined") return;

    // 请求开始时更新状态
    setLoading(true);
    setError(null);

    fetch(u)
      .then(response => {
        if (!response.ok) throw new Error('数据请求失败');
        return response.json();
      })
      .then(data => {
        // 将获取到的原始数据存入状态
        setChartData(data);
      })
      .catch(err => {
        setError(err.message);
      })
      .finally(() => {
        setLoading(false);
      });
  },[u]);

步骤2:转换数据适配图表组件格式

Cube.js的/sql接口返回的是原始数据库查询结果,你需要把它转换成图表组件需要的结构(比如折线图/柱状图需要的labelsdatasets):

// 用useMemo缓存转换后的数据,避免不必要的重计算
  const transformedData = useMemo(() => {
    if (!chartData) return null;
    
    // 假设返回的data是查询结果数组,结构类似:
    // [{line_items__created_at_day: "2024-01-01", line_items__count: 10}, ...]
    return {
      labels: chartData.map(item => item.line_items__created_at_day),
      datasets: [{
        label: '每日订单数量',
        data: chartData.map(item => item.line_items__count),
        borderColor: '#1976d2',
        fill: false
      }]
    };
  }, [chartData]);

步骤3:替换渲染逻辑,使用自定义数据

原来的代码里同时用了fetchuseCubeQuery,这会造成逻辑重复。如果你想自己控制数据请求,就替换掉useCubeQuery的逻辑,直接把转换后的数据传给图表组件:

const { chartType, pivotConfig } = vizState;
  const component = TypeToMemoChartComponent[chartType];

  // 处理加载、错误和空数据的状态提示
  if (loading) return <div>数据加载中...</div>;
  if (error) return <div>加载出错:{error}</div>;
  if (!chartData || !transformedData) return <div>暂无数据</div>;

  // 将转换后的数据传入图表组件
  return component && renderChart(component)({
    data: transformedData,
    pivotConfig,
    // 按需添加图表组件需要的其他props
  });
};

额外优化:直接使用Cube.js官方hooks简化代码

其实你可以不用自己写fetch,Cube.js提供的useCubeQuery已经帮你封装了数据请求、缓存、状态管理等逻辑,用它会更简洁:

import { useCubeQuery } from '@cubejs-client/react';

const ChartRenderer = ({ vizState }) => {
  const { query, chartType, pivotConfig } = vizState;
  const component = TypeToMemoChartComponent[chartType];
  
  // useCubeQuery自动处理数据请求,返回加载、错误、结果集等状态
  const { loading, error, resultSet } = useCubeQuery(query);

  if (loading) return <div>数据加载中...</div>;
  if (error) return <div>加载出错:{error.message}</div>;
  if (!resultSet) return <div>暂无数据</div>;

  // 用resultSet的内置方法转换数据
  const transformedData = {
    labels: resultSet.categories().map(c => c.title),
    datasets: resultSet.series().map(s => ({
      label: s.title,
      data: s.values
    }))
  };

  return component && renderChart(component)({
    data: transformedData,
    pivotConfig
  });
};

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

火山引擎 最新活动