React中使用异步接口返回对象数据渲染Chart图表的问题求解
问题根源
你当前的代码存在两个核心问题导致图表无法正常渲染:
- 你使用普通JS变量存储
timestamps和prices,没有纳入React的状态管理体系,就算异步请求返回后填充了数组,React也感知不到数据变化,不会触发组件重渲染,图表永远只能拿到初始的空数组。 - 没有请求完成判断逻辑,组件一挂载就直接渲染图表,此时异步请求还没返回,图表传入的是空数据。
另外原代码里还存在语法错误:get.data.prices[i].[0]多了多余的.,正确写法是get.data.prices[i][0]。
修改方案
我们用React的useState管理图表数据和加载状态,等异步请求完成、数据填充完毕后再触发重渲染展示图表:
import { useEffect, useState } from 'react'; import { Line } from 'react-chartjs-2'; const MarketAPI = require('market-api'); const Client = new MarketAPI(); function GRAPH(){ // 用state管理图表数据和加载状态 const [timestamps, setTimestamps] = useState([]); const [prices, setPrices] = useState([]); const [isLoading, setIsLoading] = useState(true); const getData = async() => { const fromTS = (Date.now() / 1000 | 0 ) - 86400; // 取1天前的时间戳 const toTS = Date.now() / 1000 | 0; // 取当前时间戳 let get = await Client.assets.fetchAssetHist('MSFT', { from: fromTS, to: toTS, }); const tempTimestamps = []; const tempPrices = []; for(let i = 0; i < get.data.prices.length; i++){ // 修复原代码多余的.语法错误 tempTimestamps.push(get.data.prices[i][0]); tempPrices.push(get.data.prices[i][1]); } // 更新state触发重渲染 setTimestamps(tempTimestamps); setPrices(tempPrices); setIsLoading(false); } const data = { labels: timestamps, datasets: [ { data: prices, fill: true, backgroundColor: 'rgba(243, 230, 200, 0.2)', borderColor: 'rgba(243, 210, 18)', }, ], }; const options = { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { x: { grid: { display: false }, display:true }, y: { grid: { display: false }, display: false } }, elements: { point:{ radius: 0 } }, }; useEffect(()=>{ getData() },[]); // 加载中展示占位,数据就绪再渲染图表 return( <div> {isLoading ? <p>数据加载中...</p> : <Line data={data} options={options}/>} </div> ); } function App() { return ( <GRAPH/> ); }
改动说明
- 新增
useState定义的三个状态:时间戳数组、价格数组、加载状态,状态更新会触发组件自动重渲染 - 异步请求获取到数据后,先把数据存入临时数组,再一次性更新状态,避免多次重渲染
- 组件渲染时先判断加载状态,加载完成且数据填充完毕后才渲染Line图表,保证图表拿到的是完整数据
内容的提问来源于stack exchange,提问作者subprimeloads
相关产品推荐
相关产品推荐

