Introduction
In this blog, we will dive into building a Tic-Tac-Toe game using React. Throughout the process, we will explore essential React concepts such as props, hooks (specifically useState and useEffect), and leverage the power of a 2-D array to create the game's logic. By the end of this tutorial, you'll have a solid understanding of these key concepts and be able to apply them in your React projects.
File and folder structure
- Initializing a new React project using create-react-app.
create-react-app
Inside the 'src' folder, creating a new directory named 'components'.
Inside the 'components' folder, creating a new file named 'Board.jsx' it will represents the game board.
Inside the 'components' folder, creating a new file named 'Square.jsx' it will represents each cell on the board.
Square.jsx code
import React from "react";
const Square = (props) => {
return (
<div
onClick={props.onClick}
style={{ border: "1px solid", height: "100px", width: "100%", display: "flex", justifyContent: "center", alignItems: "center" }}
className="square">
<h5>{props.value}</h5>
</div>
);
};
export default Square;
This code is a React component called "Square" that represents a square element. It has a <div>
element with a click event handler and a border. Inside the square, there's an <h5>
heading element that displays the value passed as a prop. It is exported as the default export.
Board.jsx code
import React, { useState } from "react";
import Square from "./Square";
const Board = () => {
const [state, setState] = useState(Array(9).fill(null));
const [isXTurn, setIsXTurn] = useState(true);
const checkWinner = () => {
const winnerLogic = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for(let logic of winnerLogic) {
const [a, b, c] = logic;
if(state[a] !== null && state[a] === state[b] && state[a] === state[c]){
return state[a];
}
}
return false;
};
const isWinner = checkWinner();
const handleClick = (index) => {
const copyState = [...state];
copyState[index] = isXTurn ? "X" : "O";
setState(copyState);
setIsXTurn(!isXTurn);
};
return (
<div className="board-container">
{isWinner ? (
<>{isWinner} won the game</>
) : (
<>
<div className="board-row">
<Square onClick={() => handleClick(0)} value={state[0]} />
<Square onClick={() => handleClick(1)} value={state[1]} />
<Square onClick={() => handleClick(2)} value={state[2]} />
</div>
<div className="board-row">
<Square onClick={() => handleClick(3)} value={state[3]} />
<Square onClick={() => handleClick(4)} value={state[4]} />
<Square onClick={() => handleClick(5)} value={state[5]} />
</div>
<div className="board-row">
<Square onClick={() => handleClick(6)} value={state[6]} />
<Square onClick={() => handleClick(7)} value={state[7]} />
<Square onClick={() => handleClick(8)} value={state[8]} />
</div>
</>
)}
</div>
);
};
export default Board;
This code is a React component representing a tic-tac-toe game board. It keeps track of the board state using the state
variable and the current turn using the isXTurn
variable. It has a checkWinner
function to determine if there is a winner. The handleClick
function updates the board state when a square is clicked. The component renders the board and displays the winner if there is one.
App.js
Now we have to import file into App.js to render it into webpage.
import './App.css';
import Board from './components/Board';
function App() {
return (
<div className="App">
<Board />
</div>
);
}
export default App;
Design (CSS) -> App.css
We aim to streamline the development process by utilizing straightforward and concise CSS code, ensuring simplicity and efficiency in our approach.
.board-row {
display: flex;
justify-content: space-evenly;
align-items: center;
}
.board-container {
margin: 20px;
}
Final result
Final result/ UI will look like this :-
Git Repo :- https://github.com/MAYANK-TRIPATH/Tic-Tac