this is my code so far by following official react js tutorial of making a tic-tac-toe game, I able to complete the game, but struct on the 1st challenge of create square using loop instead of hardcoding it, as you can see the comment part of code.
import { useState } from "react";
function Square({ value, onSquareClick }) {
return (
<button className="square" onClick={onSquareClick} >{value}</button>
);
}
function CreateSquares(squares, handleClick) {
const data = [];
for (let i = 0; i < 3; i++) {
const rows = [];
for (let j = 0; j < 3; j++) {
rows.push(
<Square value={squares[j]} onSquareClick={() => handleClick(j)} key={j} />
);
}
data.push(
<div className="board-row" key={i}>{rows}</div>
);
}
return data;
}
function Board({ xIsNext, squares, onPlay }) {
let winner = calculateWinner(squares);
function handleClick(index) {
if (squares[index] || winner) {
return;
}
const nextSquares = squares.slice();
nextSquares[index] = xIsNext ? 'X' : 'O';
onPlay(nextSquares);
}
let status = winner ? "Winner: " + winner : "Next Player: " + (xIsNext ? "X" : "O");
return (
<>
<div className="status">{status}</div>
<CreateSquares squares={squares} handleClick={handleClick} />
{/* <div className="board-row">
<Square value={squares[0]} onSquareClick={() => handleClick(0)} />
<Square value={squares[1]} onSquareClick={() => handleClick(1)} />
<Square value={squares[2]} onSquareClick={() => handleClick(2)} />
</div>
<div className="board-row">
<Square value={squares[3]} onSquareClick={() => handleClick(3)} />
<Square value={squares[4]} onSquareClick={() => handleClick(4)} />
<Square value={squares[5]} onSquareClick={() => handleClick(5)} />
</div>
<div className="board-row">
<Square value={squares[6]} onSquareClick={() => handleClick(6)} />
<Square value={squares[7]} onSquareClick={() => handleClick(7)} />
<Square value={squares[8]} onSquareClick={() => handleClick(8)} />
</div> */}
</>
);
}
export default function Game() {
const [history, setHistory] = useState([Array(9).fill(null)]);
const [currentMove, setCurrentMove] = useState(0);
const xIsNext = currentMove % 2 === 0;
const currentSquares = history[currentMove];
function handlePlay(nextSquares) {
const nextHistory = [...history.slice(0, currentMove + 1), nextSquares];
setHistory(nextHistory);
setCurrentMove(nextHistory.length - 1);
}
function jumpTo(nextMove) {
setCurrentMove(nextMove);
}
const moves = history.map((squares, move) => {
let description = move > 0 ? 'Go to move #' + move : "Go to game start";
return (
<li key={move}>
<button onClick={() => { jumpTo(move) }}>{description}</button>
</li>
);
});
return (
<div className="game">
<div className="game-board">
<Board xIsNext={xIsNext} squares={currentSquares} onPlay={handlePlay} />
</div>
<div className="game-info">
<ol>{moves}</ol>
</div>
</div>
);
}
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
let len = lines.length;
for (let i = 0; i < len; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
this is the error i’m getting and i’m not able to figure out how to fix this.
handleClick is not a function
TypeError: handleClick is not a function
at onSquareClick (http://localhost:3000/main.9d076070d9e17e2c1932.hot-update.js:51:30)
at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:10826:18)
at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:10870:20)
at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:10927:35)
at invokeGuardedCallbackAndCatchFirstError (http://localhost:3000/static/js/bundle.js:10941:29)
at executeDispatch (http://localhost:3000/static/js/bundle.js:15085:7)
at processDispatchQueueItemsInOrder (http://localhost:3000/static/js/bundle.js:15111:11)
at processDispatchQueue (http://localhost:3000/static/js/bundle.js:15122:9)
at dispatchEventsForPlugins (http://localhost:3000/static/js/bundle.js:15131:7)
at http://localhost:3000/static/js/bundle.js:15291:16
i’m trying to learn react and struct here, I already studied official quick start guide 2-3 times, but still not able to figure out what i am doing wrong, any help will be appreciated
3
Answers
Made it working and here is the working solution
I needed to pass
and need to do this
instead of this
In this code, we moved the
handleClick
function outside theBoard
component so that it can be accessed from outside. We also renamed the function tohandleClickOutsideBoard
to avoid any potential type errors. You can then call thehandleClickOutsideBoard
function from anywhere outside the Board component.in this part of code i think you’re incorrectly calling handleClick function ( i.e wrong index being passed , instead you have to pass unique index for each square based on rows and col ).
try this and let me know :