Yasin Issa Aden
Yasin Issa Aden

Reputation: 147

component wont render when is useEffect() is ran once

So I have the following code, where I'm fetching data to be rendered in my component. However, if the useEffect is set to run once, it wont render the data inside the component, and having it constantly running is not sustainable.

import React, { useState, useEffect } from "react";
import Chart from "react-google-charts";


const Bottom5 = ({ company }) => {
    const [quiz, setQuiz] = useState('');
    const [dataPoints, setDatapoints] = useState([]);

    useEffect(() => {
            var resultData = [];
            fetch(`http://localhost:3001/company/dashboard/bottom5/${company}`)
            .then(function(response) {
                return response.json();
            })
            .then(function(data) {
                for (var i = 0; i < data.length; i++) {
                    resultData.push({
                        label: data[i].name,
                        y: data[i].sumCorrect
                    });
                }
               setDatapoints(resultData)
            });
    },[])


    return (
            <Chart style={{display:"inline-block"}}
                width={'500px'}
                height={'300px'}
                chartType="ColumnChart"
                loader={<div>Loading Chart</div>}
                data={[
                    ['Names', 'Result'],
                    ...dataPoints.map(d => [d.label, d.y])
                ]}
                options={{
                    title: 'CyberSecurity Bottom 5',
                    chartArea: { width: '50%' },
                    hAxis: {
                        title: 'Employees',
                        minValue: 0,
                    },
                    vAxis: {
                        title: 'Total Correct',
                    },
                }}
                // For tests
                rootProps={{ 'data-testid': '1' }}
            />
    )
}

export default Bottom5;

Upvotes: 1

Views: 196

Answers (2)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196207

Could it be that when you first mount the component you have not passed a company to it ?

Normally since the code depends on the value of company, it is a good idea to add company to the useEffect dependency list.

useEffect(() => {
  var resultData = [];
  if (company) {
    fetch(`http://localhost:3001/company/dashboard/bottom5/${company}`)
      .then(function(response) {
        return response.json();
      })
      .then(function(data) {
        for (var i = 0; i < data.length; i++) {
          resultData.push({
            label: data[i].name,
            y: data[i].sumCorrect
          });
        }
        setDatapoints(resultData)
      });
  }
}, [company])

This way it will only be called whenever the company property is changed.

Upvotes: 1

Sanskar Dahiya
Sanskar Dahiya

Reputation: 309

There is an issue with update the array using hooks.

setDatapoints(resultData) // reference is same - not updating
setDatapoints([...resultData]) // do this << --

The reference of an array does not change, so hooks doesn't update itself.

Upvotes: 0

Related Questions