I am trying to render a chart that shows weight-loss over X amount of days. I created a RESTful API Endpoint that uses a json file for data and I'm trying to connect that data to the chart.
In my function below, I attempt to fetch the data, but it prints out a empty array 4 times. I don't understand why its firing 4 times.
However it gets weirder. If I input dummy data into the chart, and then add regime[0]['weight'] into the data-set, it will work temporarily. Refreshing the page causes it to break again though.
I am a bit lost on why I am returning no data at first on my response requests, and then later its available. This is causing the chart to break as it keeps reading no data is available.
App.js
import './App.css';
import { useState } from "react";
import React, { useEffect } from "react";
import axios from 'axios'
import Chart from 'react-apexcharts'
function App() {
return (
<div className="App">
<header className="App-header">
<MyRegimeChart />
</header>
</div>
);
}
function MyRegimeChart(){
const [regime, setRegime] = useState([])
useEffect(() => {
axios
.get('http://localhost:3001/regime')
.then(response => {
setRegime(response.data)
})
}, [])
console.log(regime);
return (
<Chart
type="area"
width={700}
height={450}
series={[
{
name: 'Shawn',
data: [175, regime[0]['weight'], 160, 155, 150, 145, 140],
color: '#ff0000'
}
]}
options={{
// colors:["#ff0000", "#0000ff"]
theme: {
mode: 'dark'
},
chart: {
stacked:false
},
tooltip:{
followCursor:true
},
xaxis:{
tickPlacement: 'on',
categories:[1, 2, 3, 4, 5, 6, 7],
title:{
text: "Days",
style:{
color:'white'
}
}
},
yaxis:{
title:{
text: "Weight",
style:{
color: 'white'
}
}
},
legend:{
show:true,
position:'right'
},
title:{
text: 'Weight Loss',
style: {
fontSize: 24
}
},
subtitle:{
text: 'Weight loss over months'
}
}}
>
</Chart>
)
}
export default App;
Json File:
{
"regime": [
{
"day": "May 27th, 2022",
"weight": 166.2,
"meals": ["Nachoes", "Garlic Jerky"],
"workout": "Body Combat 69"
},
{
"day": "May 26th, 2022",
"weight": 166.4,
"meals": ["Breakfast", "Steak and Kale"],
"workout": "Body Combat 41"
}
]
}
When I load the page for the first time, it returns 4 empty arrays.
If I edit the chart dataset from a random number to regime[0]['weight'] after the page has already loaded up, it will work. Refreshing the page breaks it again though.
CodePudding user response:
Prevent you component from rendering the chart until the data is available. The best way is to add an if condition like below:
{ regime.length && <Chart>...</Chart>}
CodePudding user response:
When fetching data from server, the app needs time to download. During while, data will be empty. So, you need to add a boolean called 'loading'.
function App() {
const [data,setData] = useState([]);
const [loading,setLoading] = useState(true);
React.useEffect(()=> {
// Get data from server
setData(data_of_server)
setLoading(false);
},[])
if (loading){
return <Loading />
}
return (
<Chart data={data} />
)
}
Note: have a look at 'useReducer()'.
// if you don't want new state loading
return <>
{data.length === 0 ? <Loading/> : <Chart data={data} />}
</>
CodePudding user response:
Adding to the other answers, you should valid the case when data is null, because it will be null in the first render. The first call of useEffect happens after the first render according to React documentation:
Does useEffect run after every render? Yes! By default, it runs both after the first render and after every update.