How to pass a fetched object from App.js to a child component asynchronously?
Do I have to wait for the whole data to be fetched and then return App.js? If so, How?
I'm trying to create a dashboard with react-chartjs-2 where it fetches data from the server as a whole object, however the chart loads before the fetching process, here's the code:
import './App.css';
import AvgVisitDuration from './component/AvgVisitDuration';
import Devices from './component/Devices';
import About from './component/About';
let stats;
let devices = [];
async function getStats() {
const response = await fetch('http://192.168.1.4:8080/api');
const data = response.json();
stats = data;
getDevices();
}
function getDevices() {
// Set 'devices' as a new array based on 'stats'
}
function App() {
getStats();
return (
<div className='container'>
<About />
<AvgVisitDuration />
<Devices Data={devices} /> // This is the chart component
</div>
);
}
export default App;
here we have stats as the fetched object and extracted some of the information (like stats.isMobile) into a new array called devices.
but the problem here is that when I pass the devices variable as props to <Devices /> component it only returns an empty array (the one which is first declared.)
I'll be grateful if you could tell me there is any other approach for this.
I think you are missing a lot about React fundamentals and you should go read the docs which have plenty of examples and patterns. What you want to do is make sure your component can handle a "loading" state. Async requests are not immediate and take time, what is your component going to look like while you wait for the request to complete ?
I am using a state variable to track the completion of the request. I would recommend looking up how useEffect works as well to better understand this snippet.
import AvgVisitDuration from './component/AvgVisitDuration';
import Devices from './component/Devices';
import About from './component/About';
import { useEffect, useState } from 'react';
function App() {
const [devices, setDevices] = useState([])
const [loadingDevices, setLoadingDevices] = useState(false)
useEffect(() => {
async function getStats() {
setLoadingDevices(true)
try {
const response = await fetch('http://192.168.1.4:8080/api');
const data = response.json();
const transformData = ... // do whatever you need to do to extract the data you need from the async call
setDevices(transformData)
setLoadingDevices(false)
} catch(e) {
setLoadingDevices(false)
}
}
getStats();
}, [setStats, setLoadingDevices])
return (
<div className='container'>
<About />
<AvgVisitDuration />
{loadingDevices ? <div>loading ...</div> : <Devices Data={devices} />}
</div>
);
}
export default App;