Комментарии имеют правильную идею.
Вы можете использовать шаблонный литерал и встраивать троичные условные выражения так:
return (
<td
className={`Square ${props.alive ? "active" : "inactive"}`}
onClick={() => props.alive()}
></td>
);
Быстрое обновление литералов шаблона: используйте backticks для переноса строки, и вы можете вставить в нее выражение JavaScript, обернув его в шаблон ${}
.В качестве бонуса, литералы шаблона могут занимать несколько строк, так что больше не будет неудобной конкатенации строк!
const myName = "Abraham Lincoln";
const myString = `Some text.
This text is on the next line but still in the literal.
Newlines are just fine.
Hello, my name is ${myName}.`;
Редактировать : большая проблема, которую я вижу сейчас, заключается в том, что вы не сохраняетесостояние каждой вашей клетки где угодно.У вас есть только один логический элемент, хранящийся в App
с именем alive
... что вам действительно нужно, это массив логических значений, причем каждый логический тип представляет состояние одного Square
.
Массив «живых» состояний должен находиться в App
или GameBoard
, следуя принципу React «данные стекают» .В вашем случае вы можете попытаться сохранить его в App
, и тогда GameBoard
и Square
могут остаться чисто функциональными компонентами.
Внутри App
вы можете создать новый 2-мерный массив,board
, в конструкторе и заполнить его подмассивами 0
значений изначально:
// App.js
constructor(props){
super(props);
this.state = {
boardHeight: 50,
boardWidth: 30,
board: [],
iterations: 10,
reset: false,
};
this.state.board = new Array(this.state.boardHeight).fill(new Array(this.state.boardWidth).fill(0));
}
В массиве board
каждый индекс представляет одну строку.Таким образом, упрощенный пример [[0, 0, 1], [0, 1, 0], [1, 1, 1]]
будет представлять:
0 0 1
0 1 0
1 1 1
GameBoard
должен визуализировать вашу сетку ячеек, основанную исключительно на board
пропущенной ей опоре, и передать каждому Square
его живое значениеи функция обратного вызова в качестве реквизита:
const GameBoard = (props) => {
return (
<div>
<table className="game-board">
<tbody>
{this.props.board.map((row, y) => {
return <tr key={y}>
{row.map((ea, x) => {
return (
<Square
key={x}
x={x}
y={y}
isAlive={ea}
aliveCallback={this.props.alive}
/>
);
})}
</tr>;
})}
</tbody>
</table>
</div>
);
}
Оттуда вы сможете увидеть, как это приложение будет работать.App
сохраняет состояние игры и отображает функциональный компонент GameBoard
.В GameBoard
каждый Square
рендерится в соответствии со своим живым значением и при нажатии запускает aliveCallback
.aliveCallback
должен установить состояние соответствующего значения в массиве board
внутри App
, основываясь на его x
и y
prop.