Tic Tac Toe with reactjs hooks.
Tags: beginners, react, javascript
Published: 2019-12-29 21:54:03

---
title: Tic Tac Toe with reactjs hooks.
published: true
description: 
tags: #beginner #reactjs #javascript 
---

# Here we will build a tic tac toe in reactjs:

The [react tutorial](https://reactjs.org/tutorial/tutorial.html) has done a good job explaining react with a tic tac toe, however it does not use hooks. I took another a approach and implement it with hooks which were recently added to the framework.
I hope you enjoy it. 

There are three components:
 * Square
 * Board
 * Tic Tac Toe

## Square 

Square component just receives props to pass to the parent,
these buttons represent the square that the user will interact with.
This is a stateless component since there no state changing through this component.

```jsx
export function Square({ className, buttonNumber, handleClick }) {
  return (
    <button type="button" className={className} onClick={handleClick}>
      <span>{buttonNumber}</span>
    </button>
  );
} 
```

## Board 

The board consists as the name suggests the whole board of the tic tac toe.

This component returns all Square components for the tic tac toe. Also a stateless component. 
```jsx

export function Board({ board, squareClick, isWinner, winners }) {
  const SquareType = i => {
    const classType = type => {
      return `number ${i} ${type}`;
    };
    let win = winners.some(winner => winner === i);
    if (isWinner) {
      if (win) {
        return classType("winner");
      }
    }
    return classType("lose");
  };

  return (
    <div className="board">
      {board.map((number, i) => {
        return (
          <Square
            key={i}
            className={SquareType(i)}
            buttonNumber={number}
            handleClick={() => squareClick(i)}
          />
        );
      })}
    </div>
  );
}
```

## Tic Tac Toe

This component is the parent component and uses the **useState** hook. 

The **useState** hook returns an array with two values in it, the first one is to get the current state and the second one is to set the new state.

Hooks must be declared at the top of the function. 

* ***handleMove*** : handles user interaction when clicking a button if it is X or O turn.
* ***handleSquareClick***: handles when the user clicks a button and creates a new square to save history. 
```jsx

function TicTacToe() {
  let [history, setHistory] = useState([
    {
      squares: Array(9).fill(null)
    }
  ]);
  let [move, setMove] = useState(0);
  let [turn, setTurn] = useState(false);

  let isNext = turn ? "O" : "X";

  let currentSquares = history[move].squares;
  let [isWinner, whoWin, winners] = CalculateWinner(currentSquares);

  let nturn = <h2 className="turn">Next turn? {isNext}</h2>;
  let winner = <h2 className="winner-header"> Winner {whoWin}</h2>;

  function handleSquareClick(i) {
    let current = history.slice(0, move + 1);
    let currentHistory = current[move].squares;
    const newArr = [...currentHistory];
    newArr[i] = isNext;
    setHistory(prevHistory => {
      let newHistory = {
        squares: newArr
      };
      return [...current, newHistory];
    });
    setMove(prevMove => {
      return prevMove + 1;
    });
    setTurn(prev => !prev);
  }

  function handleMove(i) {
    setMove(i);
    setTurn(prev => !prev);
  }

  function handleClear() {
    setHistory([{ squares: Array(9).fill(null) }]);
    setMove(0);
  }

  return (
    <div className="App">
      <header className="AppHeader">
        <h1 className="title">TIC TAC TOE </h1>
        {isWinner ? winner : nturn}
      </header>
      <section className="clear-game">
        <button className="clear-btn" onClick={handleClear}>
          clear game
        </button>
      </section>
      <div className="game">
        <div className="steps-moves">
          <Board
            board={history[move].squares}
            squareClick={handleSquareClick}
            isWinner={isWinner}
            winners={winners}
          />
        </div>
        <ol>
          {history.map((stp, mve) => {
            return (
              <li key={mve}>
                <div className="steps">
                  <button className="step-btn" onClick={() => handleMove(mve)}>
                    {" "}
                    Go to move # {mve}
                  </button>
                </div>
              </li>
            );
          })}
        </ol>
      </div>
    </div>
  );
}
```

source code:
{% github https://github.com/german9304/tic-tac-toe %}

Thank you and enjoy :)