I created a LineChart
using recharts and I'm pulling data using axios
from a db.json
file hosted locally by json-server. Every time I load the page or reload the chart doesn't show up. Only when I hit ctrl+s
to save my file and trigger re-render does the chart show up. How do I get the chart to show up on initial page load?
I used Vite
with SWC
to initialize the project and versions are: [email protected]
, [email protected]
, [email protected]
Chart code:
<ResponsiveContainer width="100%" height={270}>
<LineChart
width={600}
height={300}
data={monthlyData}
margin={{
left: -20,
}}
>
<CartesianGrid vertical={false} />
<Tooltip />
<XAxis axisLine={false} dataKey="name" tickSize={0} tickMargin={10} />
<YAxis
axisLine={false}
domain={[0, maxY]}
tickCount={maxY / 100 + 1}
tickSize={0}
tickMargin={10}
/>
<Line
type="monotone"
dataKey="user"
strokeWidth={2}
stroke="#9BDD7C"
dot={false}
/>
<Line
type="monotone"
dataKey="guest"
strokeWidth={2}
stroke="#E9A0A0"
dot={false}
/>
</LineChart>
</ResponsiveContainer>
This is how I'm fetching the data:
const getActivity = async (index) => {
const res = await api.get("/activity");
const data = res?.data;
setYearlyData(data);
setMonthlyData(yearlyData[index]);
};
useEffect(() => {
getActivity(0);
}, []);
setMonthlyData(yearlyData[index])
is wrong.
When you do const [yearlyData, setYearlyData] = useState([])
, yearlyData
is immutable. What setYearlyData
does is not change yearlyData
, but make it so that the next time your component runs, it will read the new value for yearlyData
. It will also queue up your component to run (i.e. re-render) when the browser gets the chance.
That means that at this time yearlyData
is still undefined. You should use setMonthlyData(data[index])
if you want to use the data you just got.
BTW this issue can be avoided if you make the initial state of yearlyData
null
. Then JavaScript will let you know there is an error with yearlyData[index]
.
If I guessed this issue wrong, you can try to debug further by inserting
console.log('yearlyData', yearlyData)
console.log('monthlyData', monthlyData)
after your useState
, and change your getActivity
to:
const getActivity = async (index) => {
console.log('fetching')
const res = await api.get("/activity");
const data = res?.data;
console.log('data', data)
setYearlyData(data);
console.log('yearlyData', yearlyData)
setMonthlyData(yearlyData[index]);
};
That should show you what's going on.