I am trying to make a tic tac toe game using reactjs. I have a function named setSquareValue to set the value of squares to X but when I am clicking on a square all the other squares also filling with X.
The hierarchy is Game.js -> Board.js -> Square.js. I am using useState() which is in Game.js and also the function setSquareValue is in Game.js. I am passign the function to Square.js through Board.js.
Here is my codes:
Game.js
import React, { useState } from 'react';
import './Game.css'
import Board from './Board';
const Game = () => {
const [value, setValue] = useState(null);
const setSquareValue = () => {
setValue("X")
}
return (
<div className='game'>
<h1 style={{color: "#fff"}}>Tic Tac Toe</h1>
<h4 style={{color: "#2D033B"}}>Winner: </h4>
<Board value={value} setSquareValue={setSquareValue} />
</div>
);
};
export default Game;
Board.js
import React from "react";
import Square from "./Square";
import "./Board.css";
const Board = ({ value, setSquareValue }) => {
const squareKeys = [1, 2, 3, 4, 5, 6, 7, 8, 9];
return (
<div className="board">
{squareKeys.map(squareKey => (
<Square
key={squareKey}
value={value}
setSquareValue={setSquareValue} />
))}
</div>
);
};
export default Board;
Square.js
import React from "react";
import "./Square.css";
const Square = ({ value, setSquareValue }) => {
return (
<div className="square" onClick={() => setSquareValue()}>
{value}
</div>
);
};
export default Square;
I want, when I click a certain square, only that square fill with X. But every square is filling with X. How can I solve this?
I tried but X is appearing in every box of the game.
Edited: Added CSS codes
Game.css
.game {
background-color: #AD7BE9;
width: 100%;
height: 100vh;
padding: 2rem;
display: flex;
flex-direction: column;
align-items: center;
}
Board.css
.board {
background-color: #645CBB;
color: #fff;
padding: 1rem;
margin-top: 1rem;
border-radius: 5px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
Square.css
.square {
border: 1px solid #fff;
height: 5rem;
width: 5rem;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
>Solution :
You are passing the value to every single square in your map function, for the solution you can move your value state and setSquareValue function to square component so that every square itself has its own value.
updated Square.js:
import React from "react";
import "./Square.css";
const Square = () => {
const [value, setValue] = useState(null);
const setSquareValue = () => {
setValue("X")
}
return (
<div className="square" onClick={setSquareValue}>
{value}
</div>
);
};
export default Square;
also you don’t need to pass value and setSquareValue from Game.js to Board.js and Square.js anymore;