我正在使用react-plotly库创建一个图表。图表中的数据是从API端点查询的。
服务文件如下所示
import React from 'react'
export default async function GetStockData(token,ticker,setData, setSuccess) {
var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer " + token)
var formdata = new FormData();
formdata.append("Tick", ticker);
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formdata,
redirect: 'follow'
};
await fetch("https://abc.azurewebsites.net/api/stocks", requestOptions)
.then(response => response.json())
.then(response => setData(JSON.parse(response.content))
}
我仍然是添加错误处理。我已经将股票代码固定为一个我知道目前有效的值。
然后,此服务由以下组件调用:
import React, { useState, useContext, useEffect} from 'react'
import GetStockData from '../Services/GetStockData'
import Plot from 'react-plotly.js';
import { sampleData } from './sampleChartdata';
import AuthContext from "../Store/AuthContext";
export default function CandleStick() {
const authCtx = useContext(AuthContext);
const token = authCtx.token
const [chartData, setChartData] = useState(sampleData);
const [chartSuccess, setChartSuccess] = useState(false)
const [preppedData, setpreppedData] = useState(null);
const [layout, setlayout] = useState(null);
const ticker = 'MSFT'
const clickHandler = async()=>{
await GetStockData(token,ticker,setChartData, setChartSuccess)
const {data, preplayout} = dataPrep()
setpreppedData(data)
setlayout(preplayout)
}
const dataPrep =()=>{
var dateData = []
var closeData = []
var openData = []
var lowData = []
var highData = []
for(var prop in chartData["Time Series (Daily)"]){
dateData.push(prop)
for(var prop2 in chartData["Time Series (Daily)"][prop]){
if (prop2=="1. open"){ openData.push(chartData["Time Series (Daily)"][prop][prop2])}
if (prop2=="2. high"){ highData.push(chartData["Time Series (Daily)"][prop][prop2])}
if (prop2=="3. low"){ lowData.push(chartData["Time Series (Daily)"][prop][prop2])}
if (prop2=="5. adjusted close"){ closeData.push(chartData["Time Series (Daily)"][prop][prop2])}
}
}
var trace1 = {
x: dateData,
close:closeData,
increasing: {line: {color: 'green'}},
decreasing: {line: {color: 'red'}},
high: highData,
line: {color: 'rgba(31,119,180,1)'},
low: lowData,
open: openData,
type: 'candlestick',
xaxis: 'x',
yaxis: 'y'
};
var data = [trace1]
var layout = {
dragmode: 'zoom',
margin: {
r: 10,
t: 25,
b: 40,
l: 60
},
showlegend: false,
xaxis: {
autorange: true,
domain: [0, 1],
title: 'Date',
type: 'date'
},
yaxis: {
autorange: true,
domain: [0, 1],
type: 'linear'
}
};
return {data , layout}
} ;
useEffect(() => {
if (preppedData !== null) setIsDataLoaded(true);console.log(preppedData)
}, [preppedData]);
return (
<>
<div>{isDataLoaded?
<Plot
data={preppedData}
layout={layout}>
</Plot>: null}
</div>
<button onClick={()=>clickHandler()}>Refresh</button>
</>
)
}
这里可能有很多东西可以改进。我使用了太多的状态变量作为开始。我目前有一个本地存储的数据作为样本,以防止在请求发出之前发生错误。任何关于等待基于Web的内容时如何管理第一次渲染的评论都将非常感谢。
我的核心问题与setChartData、setChartSuccess有关。按下按钮后,这些数据将传递到服务文件,并在服务文件中同时更新。然而,chartSuccess变量似乎在ChartData之前更新。jsx条件触发并呈现图形,但它不包含最新的preppedData。第二次按下按钮时,更新的数据出现。我是否在排序中出错了?
1条答案
按热度按时间vsnjm48y1#
在我看来,你可以做两件事来解决这个问题:要么在click处理程序中设置成功状态,如果成功状态不能移动到其他地方,因为它可能会在其他地方使用,你可以有一个新的状态变量,并使用它作为呈现与否的条件。
我在这里向您展示如何使用第二种方法,但是如果您没有我提到的问题,您可以给予第一种方法。
因此,您的组件代码将如下所示。
根据要求更新