skip to Main Content

In my React App I want to fetch data from DB every 5 seconds and display it.
The data is an array of objects:
It’s an array of "station"s each station has these properties:

  1. Name
  2. status = Run/Hold
  3. Update Time

I’m displaying all the stations and their info and also displaying a toolbar on the top that is counting the number of stations based on their status (e.g. "Running: 10, Holding: 20")

the station are in a component called "displayStations"
To achieve it I’m using a state in the displayStations that is holding the array of objects and fetches it.
Now the problem is that if I’m updating the state of the displayStations with the new array all the stations under it will get rerendered but I want only the changed stations to be rerenderd. what is the best approach on solving it?

  • Code:
function DisplayStations() {
  const [stationsData, setStationsData] = useState([]);

.
.
.

useEffect(() => {
    const fetchStationsData = async () => {
      const response = await fetch(`/stationsInfo`);
      const data = await response.json();
      setStationsData(data);
      handleStationsDataChange();
    };
    fetchStationsData();
    const fetchInterval = setInterval(() => {
      fetchStationsData();
    }, intervalTime * 1000);

    return () => {
      clearInterval(fetchInterval);
    };
  });
.
.
.
return (
    <Box>
      {stationsData.map((stationsDataObj) => {
        return <Station key={stationsDataObj['Name']} stationData={stationsDataObj} />;
      })}
    </Box>
  );
}




function Station({ stationData }) {
return (
    <div>
      <div>
        {stationData['Name']}
      </div>
      <div>
        {stationData['Status']}
      </div>
      <div>
        {stationData['updateTime']}
      </div>
    </div>
}

2

Answers


  1. To solve this problem you may have to use as:

    const fetchStationsData = async () => {
          const response = await fetch(`/stationsInfo`);
          const data = await response.json();
          setStationsData(data);
          handleStationsDataChange();
        };
    useEffect(() => {
        fetchStationsData();
        const fetchInterval = setInterval(() => {
          fetchStationsData();
        }, intervalTime * 1000);
    
        return () => {
          clearInterval(fetchInterval);
        };
      },[]); //here this will work as to display the content one
    

    May this will help you.

    Login or Signup to reply.
  2. As mentioned in the comment, you can make use of React.memo HOC to wrap your component so that it doesn’t re-render when the props are not changed.

    By default it does shallow comparison. To compare if the props are really changed you can pass function as second parameter for props comparison.

    You can do something like below.

    import { memo } from "react";
    
    const Station = ({ stationData }) => {
      return (
        <div>
          <div>{stationData["Name"]}</div>
          <div>{stationData["Status"]}</div>
          <div>{stationData["updateTime"]}</div>
        </div>
      );
    };
    
    function propsAreEqual(prevProps, nextProps) {
      return prevProps.Name === nextProps.Name;
    }
    
    export default memo(Station, propsAreEqual);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search