Reputation: 139
When I render this React component:
import React, { useState, useEffect, useCallback } from "react";
// import RenderLineChart from "../recharts/rechart.component";
import axios from "axios";
import "./chart-item.styles.scss";
const ChartItem = ({ apiUrl }) => {
const [chartData, setChartData] = useState([]);
//function that pulls data from APIs
const loadChartData = useCallback(() => {
axios.get(apiUrl).then((response) => {
setChartData(response.data);
});
}, [apiUrl]);
//runs initial pull from API
useEffect(() => {
loadChartData();
}, [loadChartData]);
console.log("Raw Data: ");
console.log(chartData);
console.log("Array: ");
console.log(chartData.historical);
// console.log("Array Element: ");
// console.log(chartData.historical[0]);
return <div className="chart"></div>;
};
export default ChartItem;
When I uncomment that third console.log statement and save the component file without refreshing localhost, the output is:
But when I actually refresh the localhost tab, the output is such:
As if it is no longer being treated as an array. Can anyone explain what's going on here?
Upvotes: 0
Views: 157
Reputation: 380
You have 2 mistakes in the snippet you posted.
You're declaring chartData
as an array, but then you're updating it with an object (inside the loadChartData
function)
When page loads the console.log
is executed before the loadChartData
function has completed the request, so at the first render chartData = [] and chartData[0] = undefined
, but if you try to get chartData.historical[0]
it throws you an error because it is defined as an array.
So, how can you fix this? The answer is pretty straightforward, first of all you have to use a consistend data-type for your state, if it's an array when declared, then when you update it, pass an array, if not you'll always have this kind of problems. This should fit your needs. If you want to log chartData
everytime it upates you just need to write a new useEffect
with the console.log
inside and chartData
as "dependency"
const [chartData, setChartData] = useState({ historical: [] })
// declare you api call
const apiCall = useCallback(() => {
try {
const response = await axios.get(url);
setChartData(response.data)
} catch (e) {
console.error(e)
}
}, [setChartData])
useEffect(() => {
apiCall()
}, [apiCall])
useEffect(() => {
console.log("Raw Data: ");
console.log(chartData);
console.log("Array: ");
console.log(chartData.historical);
console.log("Array Element: ");
console.log(chartData.historical[0]);
}, [chartData])
// do you stuff with jsx
I suggest you to take a look at Hooks Documentation
Hope this helps ✌️
Upvotes: 1