the main problem is that when I console.log "datasource" array it first shows that array populated the way I want to, which is:
[
0:{ date: date, value: value },
1:{ date: date, value: value },
...
]
but then after the first log loads it suddenly changes to a empty array [];
Here is my code:
import React, {useState, useEffect} from 'react'
import { ChartComponent, LineSeries, ColumnSeries, SeriesDirective, SeriesCollectionDirective, Inject } from '@syncfusion/ej2-react-charts'
import axios from 'axios'
const StablesTVLchart = () => {
const [stables, setStables] = useState([])
const dates = new Array;
const totalCirculating = new Array;
const totalPegged = new Array;
const datasource = new Array;
useEffect(() => {
axios.get('https://stablecoins.llama.fi/stablecoincharts/all?stablecoin=1')
.then(res => {
setStables(res.data)
// Populate dates array and totalCirculating array /
for (var i = 0; i < stables.length; i ){
dates.push(parseFloat(stables[i].date))
totalCirculating.push(data[i].totalCirculatingUSD)
}
// Populate totalPegged array /
for (var y = 0; y < totalCirculating.length; y ){
totalPegged.push(totalCirculating[y].peggedUSD)
}
// Populate datasource array with date and totalPegged /
for (var e = 0; e < datadate.length; e ){
datasource.push({ date: dates[e], value: totalPegged[e] })
}
})
.catch(err => {
console.log(err)
})
}, []);
console.log(datasource);
const primaryxAxis = {visible: false }
const primaryyAxis = { labelFormat: '${value}K', visible: false }
const palette = ["skyblue"]
return (
<div className="w-full">
<ChartComponent id="charts" primaryXAxis={primaryxAxis} primaryYAxis={primaryyAxis} palettes= {palette}>
<Inject services={[ColumnSeries, LineSeries]} />
<SeriesCollectionDirective>
<SeriesDirective dataSource={datasource} xName='date' yName='value' name='TVL'/>
</SeriesCollectionDirective>
</ChartComponent>
</div>
)
}
export default StablesTVLchart
I recon that its possible I need to somehow make this datasource array into a state array?
If anyone has any clues or an idea on how to do this, I'd be very grateful.
CodePudding user response:
As it appears from the code you provided that you are using state to store the data, but immediately trying to use it, I will remind you that React may batch multiple setState() calls into a single update for performance.
Also for improvement of the code readability, you can use something like:
useEffect(() => {
axios.get('https://stablecoins.llama.fi/stablecoincharts/all?stablecoin=1')
.then(res => {
const stables = res.data;
const dates = stables.map(item => parseFloat(item.date));
const totalCirculating = stables.map(item => item.totalCirculatingUSD);
const totalPegged = totalCirculating.map(item => item.peggedUSD);
const datasource = totalPegged.map((value, index) => ({ date: dates[index], value }));
setStables(datasource);
})
.catch(err => {
console.log(err)
});
}, []);
CodePudding user response:
The api returns a single array. You store the api's response in a state you don't use. You then store parts of the data of original response in 4 arrays by mutating them (using push
). You try to use one of the mutated arrays (datasource
) in the view, but as soon as the view is re-rendered (because of setStables(res.data)
) the array is re-created with an empty array. In addition, updating a variable/constant asynchronously, and mutating the arrays doesn't cause a re-render, and even if it would react won't detect the change, and won't change the view.
Solution:
- Use
Array.map()
to create a new array based on the api's response array - Store result of the map into the state, and use that state in your view
Example:
const StablesTVLchart = () => {
const [datasource, setDatasource] = useState([])
useEffect(() => {
axios.get('https://stablecoins.llama.fi/stablecoincharts/all?stablecoin=1')
.then(({ data }) => {
setDatasource(data.map(({ date, totalCirculatingUSD }) => ({
date: parseFloat(date),
value: totalCirculatingUSD.peggedUSD
})))
})
.catch(err => {
console.log(err)
})
}, []);
console.log(datasource);
}