Крестики-нолики
Шаг 1: Вывод полей
Сначала надо создать массив, внутри которой будут храниться поля.
const cells = [
null, null, null,
null, null, null,
null, null, null
];
Когда мы будем ставить крестик или нолик, поле будет приобретать соответствущий вид, например:
const cells = [
'O', 'X', null,
null, 'X', null,
null, 'O', null
];
Значение null означает, что поле будет пустым.
Данный массив можно сократить через код ниже:
const cells = new Array(3 * 3).fill(null);
Теперь данные поля надо вывести в React.
const cells = new Array(3 * 3).fill(null);
export function App(props) {
return (
<div className="cells">
{cells.map((symbol, i) =>
<button className="cell" key={i}>
{symbol}
</button>
)}
</div>
);
}
Вместо symbol будет выводиться элемент массива (крестик или нолик).
И оформить через CSS:
.cells {
border-left: 1px solid #9f9f9f;
border-top: 1px solid #9f9f9f;
display: grid;
grid-template-columns: repeat(3, 1fr);
width: 150px
}
.cell {
background: none;
border: none;
border-right: 1px solid #9f9f9f;
border-bottom: 1px solid #9f9f9f;
cursor: pointer;
width: 50px;
height: 50px;
}
Шаг 2: Ставить крестик или нолик
Теперь надо сделать так, чтобы при клике ставился крестик или нолик.
Сначала перенесём массив «cells» внутри React, и создадим его через хук useState() (для того, чтобы React мог работать с данным массивом).
import { useState } from 'react';
export function App(props) {
// создание массива cells через хук useState()
const [cells, setCells] = useState(() => new Array(3 * 3).fill(null));
return (
<div className="cells">
{cells.map((symbol, i) =>
<button className="cell" key={i}>
{symbol}
</button>
)}
</div>
);
}
Теперь надо повешать событие через onClick().
import { useState } from 'react';
export function App(props) {
const [cells, setCells] = useState(() => new Array(3 * 3).fill(null));
const cellClickHandle = (i) => {
setCells(lastCells => lastCells.map((cell, index) => i === index ? "X" : cell ));
}
return (
<div className="cells">
{cells.map((symbol, i) =>
<button className="cell" key={i} onClick={() => cellClickHandle(i)}>
{symbol}
</button>
)}
</div>
);
}
Теперь при клике ставится символ «X». Но надо, чтобы данные символы менялись друг на друга. Поэтому создадим состояние для текущего хода (крестик или нолик).
Также добавим проверку, что если поле заполнено, то ничего не делать (чтобы нолик не перезатирал крестик).
export function App(props) {
const [cells, setCells] = useState(() => new Array(3 * 3).fill(null));
// добавлено состояние "currentStep"
const [currentStep, setCurrentStep] = useState('X');
const cellClickHandle = (i) => {
// Если поле заполнено, то ничего не делаем
if (cells[i]) {return};
// Обновляем поля
setCells(lastCells => lastCells.map((cell, index) => i === index ? currentStep : cell ));
// Меняем шаг на другой символ
setCurrentStep(lastState => ('X' == lastState) ? 'O' : 'X');
}
// ...
}
Теперь в ячейках будет ставиться соответсвующий символ (крестик или нолик).
Поддержать автора
Все статьи создаются и поддерживаются одним человеком,
если вам нравится контент, вы можете поддержать автора сайта
