Как поддерживать большое динамическое состояние React, определяющее дочерние элементы?
У меня есть компонент React с сокетом, который получает информацию, обновляющую его состояние. В конечном итоге состояние представляет собой около 10000 объектов JSON, каждый из которых представляет pointPrimitive для рендеринга в приложении цезия/резиума. Редактирование этого списка несколько раз в секунду обходится дорого, и даже оценка необходимости повторного рендеринга запомненных дочерних элементов обходится дорого в таком масштабе. Что я могу сделать, чтобы этот компонент работал с разумной скоростью или реорганизовал его?
import React from 'react';
import { useState, useEffect } from 'react';
import { io } from "socket.io-client";
import PointCollection from '../TrackPoints/PointCollection';
import { getServerURL } from '../../lib/getServerURL';
const enoughPoints = 1;
const delayMSec = 1000 * .5;
const expireSec = 45; //This should depend on the class of item. Maybe anomalous things should last longer
const serverURL = getServerURL();
const PointManager = (props: {modes: any, onClick: Function, viewRef}) => {
const [pointsDict, setPointsDict] = useState({});
const mode = props.modes.ADSB;
//TODO: figure out whether to use a list of JSONs or a proper list of components
//There may be performance consequences to either. For now, this is cleaner to code
const addPoint = (JSONEntry) => {
const k = JSONEntry.react_key;
const oldJSON = pointsDict[k] === undefined ? [] : pointsDict[k];
let newJSON = JSONEntry;
if (oldJSON.length > 0) {
newJSON.isAnomalous = oldJSON[oldJSON.length-1].isAnomalous;
} else {
newJSON.isAnomalous = false;
}
setPointsDict((pointsDict) => {
const copyFoo = { ...pointsDict};
if(copyFoo[k] === undefined) {
copyFoo[k] = [newJSON];
return copyFoo;
}
copyFoo[k].push(newJSON);
globalThis.SCJJ = copyFoo;
return copyFoo;
});
};
const staleOutPoints = (expireSec: number) => {
setPointsDict((pointsDict) => {
const keys = Object.keys(pointsDict);
const t = Date.now()/1000;
let newPoints = {};
keys.map((trackID) => {
const pts = pointsDict[trackID];
let ptsFilter = pts.filter((pt,idx) => t - pt.TIMESTAMP < expireSec);
newPoints[trackID] = ptsFilter;
});
return newPoints;
});
};
//Control point time-out
useEffect(() => {
const interval = setInterval(() => staleOutPoints(expireSec), delayMSec);
return () => clearInterval(interval);
}, []);
//points socket
useEffect(() => {
const format = (mode == "live" ? "LIVE" : "DEMO");
console.log("Setting up stream with format " + format);
const socketIOSocket = io(serverURL,{});
async function fetchStream() {
socketIOSocket.on('connect', function() {
console.log('connected to points server!')
socketIOSocket.emit('please_send_JSON', {
"format_requested": format,
})
});
socketIOSocket.on('JSON_entry', function(msg) {
addPoint(msg);
});
}
fetchStream();
return () => {
console.log("cleanup called");
socketIOSocket.disconnect();
};
}, [mode]);
return(
<>
{/* These are all rendering with every new point. Maybe there's a way to prevent this*/}
<PointCollection points={pointsDict}></PointCollection>
</>
)
};
export default PointManager;
Я многое сделал, чтобы уменьшить время рендеринга дочерних элементов и обеспечить минимальный повторный рендеринг родительского компонента. Я пробовал сгладить