Home > Blockchain >  Why doesn't useEffect render my graph on startup?
Why doesn't useEffect render my graph on startup?

Time:03-23

I'm creating graphs with ApexCharts in React. I'm new to both so this might be something obvious: My graphs don't render when I first load the webste, or reload it. It does render however when I change something inside of the UseEffect.

EDIT: Think it might have to do with the Async Axios call. The components are rendered before the call. Any idea how I can delay this without removing the async from axios (that will break it)?

My App.js:

import './App.css';
import React, { useEffect } from 'react';
import axios from 'axios'
import BarChart from './components/BarChart';
import GraphChart from './components/GraphChart';
import _, { orderBy } from 'lodash'



const config = {
'Content-Type': 'application/json',
"Accept": "application/json",
}

const arrayElements = [];

const App = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(async () => {
const { data } = await axios({ url: 'http://192.168.*/', method: 'GET', data: null, withCredentials: true, headers: config })

data.value.forEach(d => {

  const IdNumber= d._IdNumber
  const dateValue = d._dataValue
  arrayElements.push({ IdNumber, dateValue })
})

}, [])

return (
<div className="app">
<div className="example">
<div id="wrapper">`
<BarChart
arrElements={arrayElements}
/>
</div>
<div id="wrapper">
<GraphChart
arrElements={arrayElements}
/>
</div>
</div>
</div>
);
}

export default App;

My Graph:

import React, { useEffect, useState } from 'react' 
import Chart from 'react-apexcharts'
import _ from 'lodash'

const GraphChart = ({ arrElements}) => {
const [category, setCategory] = useState([])
const [data, setData] = useState([])

useEffect(() => {
    let series = [];
    let categories = [];
    let orderedArrElements= _.orderBy(arrElements, ['dateValue'], ['asc', 'desc'])
    for (let i = 0; i < orderedArrElements.length; i  ) {
        series.push(
            orderedArrElements[i].IdNumber
        )
        categories = categories.concat(orderedArrElements[i].dateValue)
    }
    console.log(categories)

    setCategory(categories)
    setData(series)
    console.log("is called")
}, [arrElements])

return (
    <div>
        <Chart
            options={{
                chart: {
                    id: "basic-graph",
                },
                stroke: {
                    curve: 'smooth',
                    colors: ['#00BAEC']
                },
                grid: {
                    row: {
                        colors: ['#f3f3f3', 'transparent'],
                        opacity: 0
                    },
                },
                fill: {
                    gradient: {
                        enabled: true,
                        opacityFrom: 0.65,
                        opacityTo: 0
                    }
                },
                markers: {
                    size: 5,
                    colors: ["#000524"],
                    strokeColor: "#00BAEC",
                    strokeWidth: 3
                },
                dataLabels: {
                    enabled: false
                },
                xaxis: {
                    categories: category,
                    labels: {
                        style: {
                            colors: '#fff'
                        }
                    }
                },
                yaxis: {
                    labels: {
                        style: {
                            colors: '#fff'
                        }
                    }
                },
            }}
            series={[{
                name: "ID",
                data: data
            }
            ]}
            type="area"
            width={2000}
            height={1000} />
    </div>


   )
}

export default GraphChart

It did render when all the code was in the App.js.

CodePudding user response:

You should use a state to keep track of arrayElements.

The way you do it now, the graph components are rendered with arrayElements = []. In the next step data is appended to arrayElements, but this isn't noticed by React so the graphs aren't rerendered.

If you initialize arrayElements as const [arrayElements, setArrayElements] = useState([]) and update the data per below, then React will notice the change and rerender the graph components as soon as the data is received.

const newData = data.value.map(d => {

  const IdNumber= d._IdNumber
  const dateValue = d._dataValue
  return { IdNumber, dateValue }
})
setArrayElements(newData)
  • Related