Others have mentioned efficient ways to work with immutable data structures, but I want to mention another solution:
In cases where I want to get ideal performance, I sometimes separate out a plain JavaScript service and wrap it in a React hook.
So for example, let’s say you have a massive array of like 100,000 objects. You presumably aren’t putting that entire array on the screen at once. So you could keep the array in a normal JavaScript class, keep in instance of that class in state, fire events into it, and then query out the slices of data you actually need.
Those smaller slices can be generated each time there is a state change, but you don’t need to re-allocate the big array.
Even if you do need to show the entire array, say as a data plot, you can render directly to a canvas, but still wrap that canvas and the I/O in a React hook. React works quite well with these “plain JavaScript” escape hatches in the rare case they’re needed.
The other place I’ve been using this approach is for drag and drop hooks, where the complexity of managing React renders and coordinating state changes on every mouse move is just too much. Instead I have service class that updates the few DOM nodes that need to be changed every frame, and I only fire off state changes when there are meaningful transitions (hover over something, drop something, etc.)
In cases where I want to get ideal performance, I sometimes separate out a plain JavaScript service and wrap it in a React hook.
So for example, let’s say you have a massive array of like 100,000 objects. You presumably aren’t putting that entire array on the screen at once. So you could keep the array in a normal JavaScript class, keep in instance of that class in state, fire events into it, and then query out the slices of data you actually need.
Those smaller slices can be generated each time there is a state change, but you don’t need to re-allocate the big array.
Even if you do need to show the entire array, say as a data plot, you can render directly to a canvas, but still wrap that canvas and the I/O in a React hook. React works quite well with these “plain JavaScript” escape hatches in the rare case they’re needed.
The other place I’ve been using this approach is for drag and drop hooks, where the complexity of managing React renders and coordinating state changes on every mouse move is just too much. Instead I have service class that updates the few DOM nodes that need to be changed every frame, and I only fire off state changes when there are meaningful transitions (hover over something, drop something, etc.)