skip to Main Content

Here is the React component that is causing me issues…

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 = () => {
  const [dataSet, setDataset] = useState([0]);
  const labels = useRef([0]);

  useEffect(() => {
    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, newValue];
        }
      });
    }, 1000);
  }, []);

  const data = {
    labels: labels.current,
    datasets: [
      {
        data: dataSet,
      },
    ],
  };
  return (
    <div className={styles.graph}>
      <Line data={data}></Line>
    </div>
  );
};

export default LineGraph;

The issue is that 2 values are getting added to the state array because the setInterval function is being called twice for some reason, I would highly appreciate an explanation as to why this is happening.

2

Answers


  1. Are you using strict mode? Then it is totally normal that your code gets executed twice. You should also add a cleanup function to your useEffect to prevent that the interval is running 2 times.

     useEffect(() => {
    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, newValue];
        }
      });
       return () => {
            clearInterval(interval);
        }
    
    }, 1000);
    

    }, []);

    Login or Signup to reply.
  2. Your application seems completely fine.
    This might be caused due to <React.StrictMode> wrapping your <App />.

    StrictMode renders components twice to identify any issues and warn you about them. One thing to keep in note is that this only happens on dev and not in production.

    You can disable strict mode by removing the <React.StrictMode> wrapper.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search