I have a react component, which gets some data from backend and shows the result in a piechart.
function SiteInfo() {
const [url, setUrl] = React.useState('Loading...')
const [title, setTitle] = React.useState('Loading...')
const [uptime, setUptime] = React.useState(0)
const [uptimeData, setUptimeData] = React.useState([])
const [online, setOnline] = React.useState(false)
const [latency, setLatency] = React.useState(-1)
const [searchParams, _] = useSearchParams()
const siteid = searchParams.get('siteid')
React.useEffect(() => {
(async () => {
const response = await fetch(`http://localhost:3000/siteinfo/${siteid}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`
}
})
const siteinfo = await response.json()
const sitedata = siteinfo.sitedata
console.log(sitedata.uptimeData)
setUrl(sitedata.site)
setTitle(sitedata.title)
setUptime(sitedata.uptime)
setUptimeData(sitedata.uptimeData)
setOnline(sitedata.uptimeData.at(-1).up)
setLatency(sitedata.uptimeData.at(-1).latency)
})()
}, [siteid])
return (
// ...
<div>
<PieChart width={500} height={300} >
<Pie
cx='50%'
cy='50%'
data={[
{
name: 'Up',
value: uptime,
fill: '#3CFF60',
stroke: '#29D849',
},
{
name: 'Down',
value: 100 - uptime,
fill: '#FA8080',
stroke: '#F82D2D',
}
]}
dataKey='value'
>
<LabelList dataKey='name' position='outside' />
</Pie>
<Tooltip />
</PieChart>
</div>
// ...
)
}
There is an animation associated with the piechart which appears normally when I remove the line setUptimeData(sitedata.uptimeData)
, but when the line is present, the animation does not play. Even though uptimeData
is not related to the Pie chart in any way.
One thing to be noted is that the field sitedata.uptimeData
is a big array of objects (almost 20 elements), maybe it is somehow taking long to set the state and resetting the animation midway. However I cannot find a way to confirm this or an alternative way to set the state.
I am using recharts for the piechart.
Any help will be greatly appreciated.
The issue might be that updating the state triggers a re-render of the SiteInfo
component, which in turn re-renders the PieChart
. This re-rendering might interrupt the animation.
Try using React.memo to extract out a component that won't re-render.
const MemoizedPieChart = React.memo(({ uptime }) => (
<PieChart width={500} height={300}>
<Pie
cx='50%'
cy='50%'
data={[
{ name: 'Up', value: uptime, fill: '#3CFF60', stroke: '#29D849' },
{ name: 'Down', value: 100 - uptime, fill: '#FA8080', stroke: '#F82D2D' }
]}
dataKey='value'
>
<LabelList dataKey='name' position='outside' />
</Pie>
<Tooltip />
</PieChart>
));
Then, you can use MemoizedPieChart
instead.
return (
<div>
<MemoizedPieChart uptime={uptime} />
</div>
);