skip to Main Content

i am using react 18 StrictMode and i have some pages in an application while navigating from one page to another page (using Router) an empty page displaying at first and after 2 3 seconds page refreshing and displaying with data.

example i have pie chart in a page when i navigate to this page empty grid showing at first and after that page reloading and pie chart showing

i tried few ways to prevent it 1. spinner using use state, useRef check and Suspense CallBack but nothing is worked.

This is my sample code

Service.js

import axios from 'axios';
//demo code
class Service {

  async fetchData1() {
    try {
      const response = await axios.get("https//some-end-point");
      return response.data;
    } catch (error) {
      console.log('Error retrieving data:'+ error);
    }
  }

  async fetchData2(){
      try {
        const response = await axios.get("https//some-end-point");
        return response.data;
      } catch (error) {
        console.log('Error retrieving data:'+ error);
      }
  }

}
export default new Service();

Dashboard.js

import React, { useEffect, useState } from 'react';
import Service from '../services/Service';

const Dashboard = () => {
  const [BarData, setBarData] = useState([]);
  const [StatsData, setStatsData] = useState([]);
  const [PieData, setPieData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const data1 = await Service.fetchData1();
        const data2 = await Service.fetchData2();
        if (data1) setBarData(data1);
        if (data2) setStatsData(data2);
      } catch (error) {
        console.log('Error fetching data:' + error);
      }
      setIsLoading(false);
    };

    fetchData();
  }, []);

  setPieData([
    {
      label: 'Label A',
      value: StatsData['Total Data A'],
    },
    {
      label: 'Label B',
      value: StatsData['Total Data B'],
    },
  ]);

  const PieDataChart = {
    series: PieData.map(item => item.value),
    options: {
      chart: {
        type: 'pie',
        width: 300,
        height: 300,
      },
      dataLabels: {
        enabled: false,
      },
      labels: PieData.map(item => item.label),
      //some properties
    },
  };

  if (isLoading) {
    return (
      <div className="loader">
        <RingLoader color="#36D7B7" loading={true} size={100} />
      </div>
    );
  }

  return (
    <div className="page-container">
      {/* demo data*/}
      <div className="pieChart-Wrapper">
        <div className="pieChart">
          <ReactApexChart options={PieDataChart.options} series={PieDataChart.series} type="pie" />
        </div>
      </div>
    </div>
  );
};

export default Dashboard;

i want to render the page only once to prevent the empty rendering at first reload, please help me.

Thanks

2

Answers


  1. It might be related to the React StrictMode feature. It was intentionally introduced in order to avoid side effects in render phase.But page renders twice only in development mode, not in production.

    Login or Signup to reply.
  2. Here’s my solution, hope it help you

    import React, { useEffect, useState } from 'react';
    import Service from '../services/Service';
    
    const Dashboard = () => {
      const [BarData, setBarData] = useState([]);
      const [StatsData, setStatsData] = useState([]);
      const [PieData, setPieData] = useState([
        {
          label: 'Label A',
          value: 0,
        },
        {
          label: 'Label B',
          value: 0,
        },
      ]);
      const [isLoading, setIsLoading] = useState(true);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const data1 = await Service.fetchData1();
            const data2 = await Service.fetchData2();
            if (data1) setBarData(data1);
            if (data2) setStatsData(data2);
          } catch (error) {
            console.log('Error fetching data:' + error);
          }
          setIsLoading(false);
        };
    
        fetchData();
      }, []);
    
      useEffect(() => {
        if (StatsData['Total Data A'] && StatsData['Total Data B']) {
          setPieData([
            {
              label: 'Label A',
              value: StatsData['Total Data A'],
            },
            {
              label: 'Label B',
              value: StatsData['Total Data B'],
            },
          ]);
        }
      }, [StatsData]);
    
      const PieDataChart = {
        series: PieData.map(item => item.value),
        options: {
          chart: {
            type: 'pie',
            width: 300,
            height: 300,
          },
          dataLabels: {
            enabled: false,
          },
          labels: PieData.map(item => item.label),
          //some properties
        },
      };
    
      if (isLoading) {
        return (
          <div className="loader">
            <RingLoader color="#36D7B7" loading={true} size={100} />
          </div>
        );
      }
    
      return (
        <div className="page-container">
          {/* demo data*/}
          <div className="pieChart-Wrapper">
            <div className="pieChart">
              <ReactApexChart options={PieDataChart.options} series={PieDataChart.series} type="pie" />
            </div>
          </div>
        </div>
      );
    };
    
    export default Dashboard;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search