skip to Main Content

In the above component of my React project I have used setInterval to create a State Array that has a maximum size of 10 and used ChartJS to represent the changes in that Array in a Line Graph, but multi[le values are being added into the Array at a time instead of just one.

I have tried adding the useEffect hook and clearInterval functionalities to help with the predictability of the setinterval function but it hasn’t worked. Thanks in advance for any help with the code .

import styles from "./LineGraph.module.css";
import { useEffect, useState, useRef } from "react";
import { Line } from "react-chartjs-2";
import {
  Chart as ChartJS,
  LineElement,
  CategoryScale,
  LinearScale,
  PointElement,
} from "chart.js";

ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);

const Time = () => {
  let now = new Date();
  let hour = now.getHours();
  let minute = now.getMinutes();
  let second = now.getSeconds();

  return `${hour}-${minute}-${second}`;
};

const LineGraph = (props) => {
  const [dataSet, setDataset] = useState([0]);
  const labels = useRef([0]);
  const temperature=props.temperatureValue;

  useEffect(() => {
    console.log(props);
    const temperature= props.Parameters.temperature;
    console.log(props.Parameters.temperature);
    const interval = setInterval(() => {

      if (labels.current.length > 10) {
        const newLabels = dataSet.slice(1, dataSet.length);
        const newLabel = Math.floor(Math.random() * 1000);
        labels.current.value = [...newLabels, newLabel];
      } else {
        labels.current = [...labels.current, Time()];
      }
      setDataset((dataSet) => {
        if (dataSet.length > 10) {
          const newDataSet = dataSet.slice(1, dataSet.length);
          const newValue = Math.floor(Math.random() * 1000);
          return [...newDataSet, newValue];
        } else {
          const newValue = Math.floor(Math.random() * 1000);
          return [...dataSet, temperature];

        }
      });
      return () => {
        clearInterval(interval);
      };
    }, 10000);
  }, [props]);

  const data = {
    labels: labels.current,
    datasets: [
      {
        data: dataSet,
        fill: true,
        backgroundColor: "rgb(92, 158, 231)",
        borderColor: "rgb(92, 158, 231)",
        pointRadius: 5,
        pointHoverRadius: 8,
        pointBackgroundColor: "rgb(92, 158, 231)",
        pointBorderColor: "rgb(92, 158, 231)",
        pointHoverBackgroundColor: "rgb(92, 158, 231)",
        pointHoverBorderColor: "rgb(92, 158, 231)",
        borderWidth: 2,
        tension: 0.5,
      },
    ],
  };
  return (
    <>
      <Line data={data}></Line>
    </>
  );
};

export default LineGraph;

2

Answers


  1. You have a problem with indentation. Here is your interval extracted. You can see that inside the setInterval you are returning a function to clear the interval.

    const interval = setInterval(() => {
      return () => {
        clearInterval(interval);
      };
    }, 10000);
    

    That doesn’t really do anything. You wanted to return that from the useEffect not setInterval.

    const interval = setInterval(() => {
    }, 10000);
    return () => {
      clearInterval(interval);
    };
    

    As you have it now, the cleanup is never called so it creates more and more intervals that run at the same time.

    Login or Signup to reply.
  2. It seems like there are a couple of issues in your code. Let’s address them step by step:

    if (labels.current.length > 10) {
      const newLabels = labels.current.slice(1, labels.current.length);
      const newLabel = Time();
      labels.current = [...newLabels, newLabel];
    } else {
      labels.current = [...labels.current, Time()];
    }
    

    Updating Dataset with Temperature:
    It seems like you are using temperature instead of newValue when updating the dataset. If you want to use random values for demonstration purposes, you should replace temperature with newValue. Here’s the correction:

    return [...dataSet, newValue];
    

    Or if you want to use the actual temperature data from props.temperatureValue, you can replace the line with:

    return [...dataSet, temperature];
    

    Cleaning Up Interval:
    Move the clearInterval outside the interval function, and ensure that the interval is cleared when the component unmounts. Your cleanup function should look like this:

    useEffect(() => {
      const interval = setInterval(() => {
        // ... (your existing code)
    
      }, 10000);
    
      return () => {
        clearInterval(interval);
      };
    }, [props]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search