'Without setTimeout component is not rendering the proper data

This question is merely for curiosity. So, I have a parent component that fetches some data (Firebase) and saves that data in the state, and also passes the data to the child. The child's code is the following:

import { Bar, Doughnut } from 'react-chartjs-2'
import { Chart } from 'chart.js/auto'
import { useState, useEffect } from 'react'
import _ from 'lodash'

const initialData = {
  labels: [],
  datasets: [
    {
      id: 0,
      data: [],
      backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56', '#FF6384'],
      color: ['#FF6384', '#36A2EB', '#FFCE56', '#FF6384'],
      borderWidth: 0,
    },
  ],
}

var config2 = {
  maintainAspectRatio: true,
  responsive: true,
}

export default function DoughnutChart(props) {

  const [data, setData] = useState(initialData)

  useEffect(() => {

    const newData = _.cloneDeep(initialData)
    var wins = 0
    var losses = 0
    var labels = ['wins', ' losses']
    //Whithout seTimeout the chart is not updated
    setTimeout(() => {
      props.trades.forEach((trade) => {
        if (trade.cprice) {
          if (trade.cprice >= trade.price) {
            wins++
          } else {
            losses++
          }
        }
      })
      newData.datasets[0].data = [wins, losses]
      newData.labels = labels
      setData(newData)
    }, 1000)

  }, [props.trades])



  return (
    <Doughnut
      data={data}
      options={config2}
      redraw
    />
  )
}

As you can see the child listens with useEffect to props changes, and then I process the props as I want to plot the necessary information on the Chart.

The thing is that in the beginning, the code didn't work (the Chart didn't display anything despite the props changed), I console logged the props, and it seems that something was happening too fast (if I console the length of the props.trades it showed me 0, but if I consoled the object it shows data in it) So that the forEach statement wasn't starting to iterate in the first place. When I added the setTimeout it started working if a put a 1000 milliseconds (with 500 milliseconds it doesn't work).

I'm a beginner at React and would be very interested in why this happens and what is the best approach to handle these small delays in memory that I quite don't understand.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source