This is a small game that I am developing. Screenshot
Every one of these squares are represented by an object.
{
row: i,
col: j,
isWall: false,
isVisited: false,
isPath: false,
parentRow: null,
parentCol: null,
distance: Infinity
}
isWall property corelates to the black squares.
These are stored in a 2D array in the state.
this.state = {
grid: getGrid()
}
I know we shouldn't mutate the state directly so every time I have to change a square from white to black, I copy the grid, change that square's isWall property to true and finally call setState.
getGridCopy = () => this.state.grid.map(row => row.map(square => ({...square})));
turnBlack = (row, col) => {
const grid = this.getGridCopy();
grid[row][col].isWall = true;
this.setState({
grid
})
}
(The code is stripped down to only show relevant parts)
Now imagine I have to animate the whole grid from being white to completely black one square at a time. There are hundreds of squares in the grid and I have to change every one of them to black and to change just one square, I have to copy the whole 2D array of objects. This turns out to be very resource heavy that I can visibly see stutters in the animation. The animation is really smooth when I change the state directly without copying.
What do you suggest? I don't have much experience developing so any suggestions are welcome. This is the first project that is actually worth something. Can you suggest other ways of storing these objects instead of 2d arrays?
EDIT:
If there's just a single component with the whole grid as its state...
I have a Board component which has this state with grid 2d array. I mapped through the grid in board component's render method and render a Node component for each cell. Node component has no state. It receives properties as props, applies corresponding classNames to divs and renders them.
//Board component
render() {
return(
<div className="node-group">
{
grid.map((row, i) => (
<div key={i} className="node-row">
{ row.map((node, j) => <Node {...node} key={j} ></Node> ) }
</div>
))
}
</div>
)
}
//Node component
render() {
let className = 'node';
if (this.props.isWall) className += ' node-wall';
return( <div className={className} ></div> )
}
Does this qualify as each cell being it's own react component?