Hello All,
As I am learning react hooks, this is my take in changing react's tic-tac-toe game code to use hooks.
I will jump straight to code as the documentation in reactjs.org is one of the best I've ever seen. https://reactjs.org/tutorial/tutorial.html#what-are-we-building
Functions remains same as their class counterpart:
Square(props), Board(props) and calculateWinner(squares)
The "Game" component is changed to functional component and is using hooks now.
const Game = () => {
const [history,setHistory] = React.useState([{ squares: Array(9).fill(null) }]);
const [stepNumber, setStepNumber] = React.useState(0);
const [xIsNext, setXIsNext] = React.useState(true);
const [status, setStatus] = React.useState("");
const handleClick = (i) => {
const hist = history.slice(0, stepNumber + 1);
const current = hist[hist.length - 1];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = xIsNext ? "X" : "O";
setHistory(hist.concat([{ squares }]));
setStepNumber(hist.length);
setXIsNext(!xIsNext);
}
const jumpTo = (step) => {
setStepNumber(step);
setXIsNext((step % 2) === 0);
}
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}>
<button onClick={() => jumpTo(move)}>{desc}</button>
</li>
);
});
let current = history[stepNumber];
let winner = 0;
React.useEffect(()=> {
current = history[stepNumber];
winner = calculateWinner(current.squares);
if (winner) {
setStatus("Winner: " + winner);
} else {
setStatus("Next player: " + (xIsNext ? "X" : "O"));
}
});
return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={i => handleClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);
}
I am updating the status and calculating the winner in a useEffect hook as this will be called at every render (update).
The working code: https://codepen.io/kuldeep-bora/pen/QWbWPrY
Top comments (0)