Это небольшая игра, которую я разрабатываю. Снимок экрана
Каждый из этих квадратов представлен объектом.
{
row: i,
col: j,
isWall: false,
isVisited: false,
isPath: false,
parentRow: null,
parentCol: null,
distance: Infinity
}
isWall свойство соответствует черным квадратам.
Они хранятся в 2D-массиве в состоянии.
this.state = {
grid: getGrid()
}
Я знаю, что нам не следует изменять состояние напрямую, поэтому каждый раз, когда мне нужно изменить квадрат с белого на черный, я копирую сетку, изменяю свойство isWall этого квадрата на true и, наконец, вызываю 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
})
}
(Код урезан, чтобы показать только соответствующие части)
Теперь представьте, что мне нужно анимировать всю сетку от белого до полностью черного по одному квадрату за раз. В сетке сотни квадратов, и я должен изменить каждый из них на черный, а чтобы изменить только один квадрат, я должен скопировать весь 2D-массив объектов. Это оказывается очень ресурсоемким, и я могу явно видеть заикания в анимации. Анимация действительно плавная, когда я меняю состояние напрямую, без копирования.
Что вы предлагаете? У меня нет большого опыта разработки, поэтому любые предложения приветствуются. Это первый проект, который действительно чего-то стоит. Можете ли вы предложить другие способы хранения этих объектов вместо двумерных массивов?
РЕДАКТИРОВАТЬ:
Если есть только один компонент со всей сеткой в его состоянии...
У меня есть компонент Board, который имеет это состояние с массивом grid 2d. Я сопоставил сетку в методе рендеринга компонента платы и визуализировал компонент Node для каждой ячейки. Компонент Node не имеет состояния. Он получает свойства в качестве свойств, применяет соответствующие имена классов к элементам div и отображает их.
//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> )
}
Квалифицируется ли это как то, что каждая ячейка является собственным реагирующим компонентом?
@ raina770w сделал очень хорошее замечание в своем ответе. Возможно, стоит изменить архитектуру, чтобы каждый квадрат в сетке был своим собственным компонентом реакции, таким образом, обновление квадрата означает обновление только одной небольшой части дерева. Но тогда акт обновления всех квадратов с белого на черный становится техническим препятствием, но, безусловно, выполнимым.
Если нужно обновить сразу всю плату, я бы подумал о том, чтобы подготовить это состояние как готовый объект (константу) и переключать его при необходимости.