Understanding Props, Hooks, useState, useEffect by Building Tic-Tac-Toe.

Understanding Props, Hooks, useState, useEffect by Building Tic-Tac-Toe.

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

  1. Initializing a new React project using create-react-app.
create-react-app
  1. Inside the 'src' folder, creating a new directory named 'components'.

  2. Inside the 'components' folder, creating a new file named 'Board.jsx' it will represents the game board.

  3. 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