Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • React Tutorial
  • React Exercise
  • React Basic Concepts
  • React Components
  • React Props
  • React Hooks
  • React Router
  • React Advanced
  • React Examples
  • React Interview Questions
  • React Projects
  • Next.js Tutorial
  • React Bootstrap
  • React Material UI
  • React Ant Design
  • React Desktop
  • React Rebass
  • React Blueprint
  • JavaScript
  • Web Technology
Open In App
Next Article:
How to build an HTML table using ReactJS from arrays ?
Next article icon

How to build a Tic-Tac-Toe Game using React Hooks ?

Last Updated : 07 Nov, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

To build a Tic-Tac-Toe using react Hooks include the interactive components that represent the board, the signs, and at last the winner of the game.

Preview of final output: Let us have a look at how the final application will look like.

Screenshot-from-2023-11-06-11-28-45

Prerequisite of Tic-Tac-Toe Game:

  • Introduction to React
  • Functional Components in React
  • React Hooks
  • NPM & Node.js

Approach:

To create a Tic-Tac-Toe Game in React js will use the React functional components along with React JS hooks to enable the interaction and store moves. After each move, the component will switch between players and mark X or 0 on selected part the board. Style the game board using CSS for a better appearance.

Steps to Create React Application and Install required modules: 

Step 1: Use this command in the terminal to initialize the react project.

npx create-react-app tic-tac-toe-react

Step 2: Switch to the tic-tac-toe-react directory using the following command.

cd tic-tac-toe-react

Project Structure:

Example: This example implement react components and css to build a Tic-Tac-Toe game using React Hooks.

JavaScript
// Filename - App.js  // Importing the required components import Board from "./Board"; import Info from "./Info";  // Importing the CSS File import "./App.css";  // Importing the useState hook import { useState } from "react";  function App() {     // Creating a reset state, which indicates whether     // the game should be reset or not     const [reset, setReset] = useState(false);      // Creating a winner state, which indicates     // the current winner     const [winner, setWinner] = useState("");      // Sets the reset property to true     // which starts the chain     // reaction of resetting the board     const resetBoard = () => {         setReset(true);     };      return (         <div className="App">             {/* Shrinks the popup when there is no winner */}             <div                 className={`winner ${                     winner !== "" ? "" : "shrink"                 }`}             >                 {/* Display the current winner */}                 <div className="winner-text">{winner}</div>                 {/* Button used to reset the board */}                 <button onClick={() => resetBoard()}>                     Reset Board                 </button>             </div>             {/* Custom made board component comprising of              the tic-tac-toe board  */}             <Board                 reset={reset}                 setReset={setReset}                 winner={winner}                 setWinner={setWinner}             />             <Info />         </div>     ); }  export default App; 
JavaScript
// Filename - Board.js  // Importing the CSS for the board import "./css/board.css";  // Importing the useState hook, useEffect hook and useRef hook import { useState, useEffect, useRef } from "react";  const Board = ({ reset, setReset, winner, setWinner }) => {     // Creating a turn state, which indicates the current turn     const [turn, setTurn] = useState(0);      // Creating a data state, which contains the     // current picture of the board     const [data, setData] = useState([         "",         "",         "",         "",         "",         "",         "",         "",         "",     ]);      // Creating a reference for the board     const boardRef = useRef(null);      // Function to draw on the board     const draw = (event, index) => {         // Draws only if the position is not taken         // and winner is not decided yet         if (data[index - 1] === "" && winner === "") {             // Draws X if it's player 1's turn else draws O             const current = turn === 0 ? "X" : "O";              // Updating the data state             data[index - 1] = current;              //Drawing on the board             event.target.innerText = current;              // Switching the turn             setTurn(turn === 0 ? 1 : 0);         }     };      // UseEffect hook used to reset the board whenever     // a winner is decided     useEffect(() => {         // Clearing the data state         setData(["", "", "", "", "", "", "", "", ""]);          // Getting all the children(cells) of the board         const cells = boardRef.current.children;          // Clearing out the board         for (let i = 0; i < 9; i++) {             cells[i].innerText = "";         }          // Resetting the turn to player 0         setTurn(0);          // Resetting the winner         setWinner("");         setReset(false);     }, [reset, setReset, setWinner]);      // useEffect hook used to check for a winner     useEffect(() => {         // Checks for the win condition in rows         const checkRow = () => {             let ans = false;             for (let i = 0; i < 9; i += 3) {                 ans |=                     data[i] === data[i + 1] &&                     data[i] === data[i + 2] &&                     data[i] !== "";             }             return ans;         };          // Checks for the win condition in cols         const checkCol = () => {             let ans = false;             for (let i = 0; i < 3; i++) {                 ans |=                     data[i] === data[i + 3] &&                     data[i] === data[i + 6] &&                     data[i] !== "";             }             return ans;         };          // Checks for the win condition in diagonals         const checkDiagonal = () => {             return (                 (data[0] === data[4] &&                     data[0] === data[8] &&                     data[0] !== "") ||                 (data[2] === data[4] &&                     data[2] === data[6] &&                     data[2] !== "")             );         };          // Checks if at all a win condition is present         const checkWin = () => {             return (                 checkRow() || checkCol() || checkDiagonal()             );         };          // Checks for a tie         const checkTie = () => {             let count = 0;             data.forEach((cell) => {                 if (cell !== "") {                     count++;                 }             });             return count === 9;         };          // Setting the winner in case of a win         if (checkWin()) {             setWinner(                 turn === 0                     ? "Player 2 Wins!"                     : "Player 1 Wins!"             );         } else if (checkTie()) {             // Setting the winner to tie in case of a tie             setWinner("It's a Tie!");         }     });      return (         <div ref={boardRef} className="board">             <div                 className="input input-1"                 onClick={(e) => draw(e, 1)}             ></div>             <div                 className="input input-2"                 onClick={(e) => draw(e, 2)}             ></div>             <div                 className="input input-3"                 onClick={(e) => draw(e, 3)}             ></div>             <div                 className="input input-4"                 onClick={(e) => draw(e, 4)}             ></div>             <div                 className="input input-5"                 onClick={(e) => draw(e, 5)}             ></div>             <div                 className="input input-6"                 onClick={(e) => draw(e, 6)}             ></div>             <div                 className="input input-7"                 onClick={(e) => draw(e, 7)}             ></div>             <div                 className="input input-8"                 onClick={(e) => draw(e, 8)}             ></div>             <div                 className="input input-9"                 onClick={(e) => draw(e, 9)}             ></div>         </div>     ); };  export default Board; 
JavaScript
// Filename - Info.js  // Importing the css for the info import "./css/info.css";  const Info = () => {     return (         <div className="info">             <div className="player">Player 1: X</div>             <div className="player">Player 2: O</div>         </div>     ); };  export default Info; 
CSS
/* index.css */  * {     -webkit-box-sizing: border-box;     -moz-box-sizing: border-box;     box-sizing: border-box; }  body {     margin: 0;     font-family: -apple-system, BlinkMacSystemFont,         "Segoe UI", "Roboto", "Oxygen", "Ubuntu",         "Cantarell", "Fira Sans", "Droid Sans",         "Helvetica Neue", sans-serif;     -webkit-font-smoothing: antialiased;     -moz-osx-font-smoothing: grayscale; }  code {     font-family: source-code-pro, Menlo, Monaco, Consolas,         "Courier New", monospace; } 
CSS
/* Filename - App.css */  @import url(  "https://fonts.googleapis.com/css2?family=Bellefair&display=swap" );  .App {     width: 100vw;     height: 100vh;     display: flex;     justify-content: center;     align-items: center;     flex-direction: column;     gap: 5vh;     backdrop-filter: 5px;     background-color: #101010; }  .winner {     transition: all ease-in 0.3s;     display: flex;     opacity: 1;     font-size: 1.5rem;     font-weight: 600;     gap: 1vh;     flex-direction: column;     justify-content: center;     align-items: center;     width: 20vw;     position: absolute;     top: 50%;     left: 50%;     transform: translate(-50%, -70%);     background-color: rgba(195, 141, 158, 0.863);     backdrop-filter: 5px;     padding: 0.5rem;     padding-bottom: 1rem;     border-radius: 10%; }  .winner-text {     padding: 0.3em 1em 0.25em;     font-weight: 600;     font-size: 2.5rem;     color: white;     font-family: "Bellefair", serif;     position: relative;     text-align: center;     line-height: 1.3; }  .shrink {     transform: scale(0.1);     opacity: 0; }  button {     background-color: #111827;     border: 1px solid transparent;     border-radius: 0.75rem;     box-sizing: border-box;     color: #ffffff;     cursor: pointer;     flex: 0 0 auto;     font-family: "Inter var";     font-size: 1.125rem;     font-weight: 600;     line-height: 1.5rem;     padding: 0.75rem 1.2rem;     text-align: center;     text-decoration: none #6b7280 solid;     text-decoration-thickness: auto;     transition-duration: 0.2s;     transition-property: background-color, border-color,         color, fill, stroke;     transition-timing-function: cubic-bezier(         0.4,         0,         0.2,         1     );     user-select: none;     -webkit-user-select: none;     touch-action: manipulation;     width: auto; }  button:hover {     background-color: #374151; }  button:focus {     box-shadow: none;     outline: 2px solid transparent;     outline-offset: 2px; }  @media (min-width: 768px) {     button {         padding: 0.75rem 1.5rem;     } } 
CSS
/* Filename - css/info.css */  .info {     width: 30vw;     display: flex;     justify-content: space-evenly;     align-items: center;     color: whitesmoke; }  .player {     border: 2px solid #f6546a;     border-radius: 5%;     padding: 0.5rem 0;     display: flex;     font-size: 1.5rem;     justify-content: center;     align-items: center;     width: 10vw; } 
CSS
/* Filename - css/board.css */  :root {     --board-background: none;     --border-color: #f6546a;     --border-thickness: 5px; }  .board {     width: 30vw;     height: 50%;     background-color: var(--board-background);     display: flex;     align-items: flex-start;     flex-direction: row;     flex-wrap: wrap; }  .input {     height: 33.33%;     width: 33.33%;     display: flex;     justify-content: center;     align-items: center;     color: whitesmoke;     font-family: "Bellefair", serif;     font-style: italic;     font-weight: 700;     font-size: 6rem; }  .input-1 {     border-right: var(--border-thickness) dashed         var(--border-color);     border-bottom: var(--border-thickness) dashed         var(--border-color); }  .input-2 {     border-right: var(--border-thickness) dashed         var(--border-color);     border-bottom: var(--border-thickness) dashed         var(--border-color); }  .input-3 {     border-bottom: var(--border-thickness) dashed         var(--border-color); }  .input-4 {     border-right: var(--border-thickness) dashed         var(--border-color);     border-bottom: var(--border-thickness) dashed         var(--border-color); }  .input-5 {     border-right: var(--border-thickness) dashed         var(--border-color);     border-bottom: var(--border-thickness) dashed         var(--border-color); }  .input-6 {     border-bottom: var(--border-thickness) dashed         var(--border-color); }  .input-7 {     border-right: var(--border-thickness) dashed         var(--border-color); }  .input-8 {     border-right: var(--border-thickness) dashed         var(--border-color); } 

Steps to Run the Application:Use this command in the terminal inside the project directory.

npm start

Output: This output will be visible on http://localhost:3000/ on the browser window.


Next Article
How to build an HTML table using ReactJS from arrays ?

T

tejsidda34
Improve
Article Tags :
  • Web Technologies
  • ReactJS
  • CSS-Properties
  • React-Questions
  • React-Hooks

Similar Reads

  • Multiplayer Tic Tac Toe Game using React & Node
    This project is a Multiplayer Online Tic Tac Toe game developed using React & NodeJS . It allows multiple users to play the classic Tic Tac Toe game in real time. The application handles basic and advanced calculations related to the game logic and ensures a smooth gaming experience. Output Prev
    6 min read
  • Create a Tic-Tac-Toe using React-Native
    In this article, we will learn how to build a Tic-Tac-Toe game using React-Native. React Native enables the application to run a single code base on multiple platforms like Android, IOS, etc. Developing the TicTacToe game application allows us to learn basic styling, app logic, user interaction, and
    4 min read
  • How to generate random colors by using React hooks ?
    In web development, colors play a vital role in creating visually appealing and engaging user interfaces. In React we may need to generate random colors dynamically. In this article, we will explore how to achieve this using React hooks, a powerful feature introduced in ReactJs. Pre-requisite:NPM
    2 min read
  • How to build an HTML table using ReactJS from arrays ?
    To build an HTML table using ReactJS from arrays we can use the array methods to iterate to iterate the elements and create the table rows Prerequisites:NPM & Node.jsReact JSJavaScript Array.map()HTML TableApproach: To build an HTML table from an array of elements using ReactJS, we can use the a
    2 min read
  • Animation and Transitions using React Hooks
    Animations allows to control the elements by changing their motions or display. Animation is a technique to change the appearance and behaviour of various elements in web pages. Transitions in CSS allow us to control the way in which transition takes place between the two states of the element. We c
    6 min read
  • How to Use ES6 Map with React State Hooks?
    In JavaScript, the Map object is a collection of key-value pairs, where keys can be of any data type. In React, managing such key-value pairs with hooks like useState can simplify handling dynamic data structures. React’s state management system allows for smooth and efficient data manipulation, mak
    6 min read
  • Create a Tic-Tac-Toe Game using jQuery
    In this post, we are going to implement 2-player tic-tac-toe using jQuery. It is quite easy to develop with some simple validations and error checks. Player-1 starts playing the game and both the players make their moves in consecutive turns. The player who makes a straight 3-block chain wins the ga
    5 min read
  • Building a Tooltip Component with React Hooks
    Building a Tooltip Component with React Hooks is straightforward and effective. Tooltips are a common UI element used to provide additional information when a user hovers over or focuses on an element. In this article, we'll build a Tooltip component using React Hooks. PrerequisitesNPM & NodeJSR
    3 min read
  • Basic Registration and Login Form Using React Hook Form
    In ReactJS, creating a form can be a nightmare as it involves handling inputs and validating inputs. React-hook-form is a ReactJS library that simplifies the process of creating forms. The library provides all the features that a modern form needs. It is simple, fast, and offers isolated re-renders
    6 min read
  • How to Create Form Builder using React and Dynamic State Management ?
    In web development building forms is a common task. However, creating dynamic forms with varying fields and configurations can be a challenge. This is where a form builder tool comes in handy. In this article, we'll learn how to build a form builder tool using React Hooks for state management, allow
    3 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences