state updating problem

Hello recently i made a custom hook that fetches the user from the db and another one that fetches data from an external api. Basically this api returns a chess fen a chess position on the chessboard and the possible moves around 8 moves i passed the fen as a prop to the chessboard component and make it as an initial value to the fen state i did that because the fen will change during the game until the moves are null. For testing i hard coded a fen and a moves vars and everything worked fine but when i switched to the custom hook it breaks as follows : When i console.log The fen state it logs undefined and nothing shows on the board ui and i think because its related to the state and the async behavior but i couldn't find a good way to make the initial state not undefined. here's some code snippets to explain more:
2 Replies
Lumberjack
Lumberjack16mo ago
const ChessBoard: FC<BoardType> = ({
theFen,
width,
orientation,
sol,
onCorrect,
onIncorrect,
onSolve,
gameStatus,
}) => {
// fen, solution, position states
const [fen, setFen] = useState(theFen);
const [solution, setSolution] = useState(sol);
const [currentPosition, setCurrentposition] = useState<positionState>();
//making the first move by the engine based on the solution rules =>
//*always the opposite side make the first move*
useEffect(() => {
setTimeout(() => {
//the solution array always have 8 moves if its less than 8 means
//the first move already has been played
if (solution.length === 8) {
const next = validateMv(
fen,
convertStringToObject(solution[0], false),
solution
);
if (next) {
setFen(next.fen);
setSolution(next.solution) setCurrentposition(objectSlicer(next.move));
}
}
}, 100);
}, [solution]);
// the core function for checking the move validation and making the autoMove *the engine next move*
const doMove = (move: string | ShortMove) => {
const next = validateMv(fen, move, solution);
if (next) {
setFen(next.fen);
setSolution(next.solution);
if (next.solution.length > 0 && solution[0] !== undefined) {
onCorrect();
const autoNext = validateMv(
next.fen, convertStringToObject(next.solution[0], false),
next.solution
);
if (autoNext) {
setFen(autoNext.fen); setSolution(autoNext.solution); setCurrentposition(objectSlicer(autoNext.move));
}
} else {
onSolve();
}
} else {
onIncorrect();
setSolution(sol);
setFen(theFen);
}
};
return (
<Chessboard onDrop={(move) => {
doMove({
from: move.sourceSquare,
to: move.targetSquare,
promotion: "q",
});
}}
/>
);
};
export default ChessBoard
const ChessBoard: FC<BoardType> = ({
theFen,
width,
orientation,
sol,
onCorrect,
onIncorrect,
onSolve,
gameStatus,
}) => {
// fen, solution, position states
const [fen, setFen] = useState(theFen);
const [solution, setSolution] = useState(sol);
const [currentPosition, setCurrentposition] = useState<positionState>();
//making the first move by the engine based on the solution rules =>
//*always the opposite side make the first move*
useEffect(() => {
setTimeout(() => {
//the solution array always have 8 moves if its less than 8 means
//the first move already has been played
if (solution.length === 8) {
const next = validateMv(
fen,
convertStringToObject(solution[0], false),
solution
);
if (next) {
setFen(next.fen);
setSolution(next.solution) setCurrentposition(objectSlicer(next.move));
}
}
}, 100);
}, [solution]);
// the core function for checking the move validation and making the autoMove *the engine next move*
const doMove = (move: string | ShortMove) => {
const next = validateMv(fen, move, solution);
if (next) {
setFen(next.fen);
setSolution(next.solution);
if (next.solution.length > 0 && solution[0] !== undefined) {
onCorrect();
const autoNext = validateMv(
next.fen, convertStringToObject(next.solution[0], false),
next.solution
);
if (autoNext) {
setFen(autoNext.fen); setSolution(autoNext.solution); setCurrentposition(objectSlicer(autoNext.move));
}
} else {
onSolve();
}
} else {
onIncorrect();
setSolution(sol);
setFen(theFen);
}
};
return (
<Chessboard onDrop={(move) => {
doMove({
from: move.sourceSquare,
to: move.targetSquare,
promotion: "q",
});
}}
/>
);
};
export default ChessBoard
type gameStatusType = "PLAYING" | "WIN" | "LOSE";

const ChessSession: FC<setGameType> = ({ setGame, user }) => {

const [gameStatus, setGameStatus] = useState<gameStatusType>("PLAYING");

const theFen =
"r4r2/2pqbppk/p2p1n1p/1p3N2/4PB2/1P1P3P/1PP3P1/R3QRK1 w - - 1 20";
// r1b4k/ppp3bp/2npq1p1/6B1/3P4/2P2Q2/PP1K2PP/4R3 b - - 1 19
const sol = ["f4h6", "g7h6", "e4e5", "d6e5", "e1e5", "e7d8", "e5f4", "f6g8"];
// const { data, error, refetch } = useFetchPuzzle();
// {
// data
// ? console.log(data.puzzles[0].fen)
// : error
// ? console.log(error)
// : refetch
// ? console.log("refeting ur stupid data")
// : "";
// }
const { data: session } = useSession();

const { mutate } = useUpdateScore(session?.user?.email);
useEffect(() => {
//Score counting
if (gameStatus === "WIN") {
mutate({ score: user?.score, state: gameStatus });
}
if (gameStatus === "LOSE") {
mutate({ score: user?.score, state: gameStatus });
}
}, [gameStatus]);
return (

<ChessBoard
gameStatus={gameStatus}
onCorrect={() => setGameStatus((prev) => "PLAYING")}
onIncorrect={() => {
setGameStatus((prev) => "LOSE");
//
}}
onSolve={() => {
setGameStatus((prev) => "WIN");
// mutate({ score: user?.score, state: gameStatus });
}}

sol={sol}

theFen={theFen}
/>{" "}
</div>



type gameStatusType = "PLAYING" | "WIN" | "LOSE";

const ChessSession: FC<setGameType> = ({ setGame, user }) => {

const [gameStatus, setGameStatus] = useState<gameStatusType>("PLAYING");

const theFen =
"r4r2/2pqbppk/p2p1n1p/1p3N2/4PB2/1P1P3P/1PP3P1/R3QRK1 w - - 1 20";
// r1b4k/ppp3bp/2npq1p1/6B1/3P4/2P2Q2/PP1K2PP/4R3 b - - 1 19
const sol = ["f4h6", "g7h6", "e4e5", "d6e5", "e1e5", "e7d8", "e5f4", "f6g8"];
// const { data, error, refetch } = useFetchPuzzle();
// {
// data
// ? console.log(data.puzzles[0].fen)
// : error
// ? console.log(error)
// : refetch
// ? console.log("refeting ur stupid data")
// : "";
// }
const { data: session } = useSession();

const { mutate } = useUpdateScore(session?.user?.email);
useEffect(() => {
//Score counting
if (gameStatus === "WIN") {
mutate({ score: user?.score, state: gameStatus });
}
if (gameStatus === "LOSE") {
mutate({ score: user?.score, state: gameStatus });
}
}, [gameStatus]);
return (

<ChessBoard
gameStatus={gameStatus}
onCorrect={() => setGameStatus((prev) => "PLAYING")}
onIncorrect={() => {
setGameStatus((prev) => "LOSE");
//
}}
onSolve={() => {
setGameStatus((prev) => "WIN");
// mutate({ score: user?.score, state: gameStatus });
}}

sol={sol}

theFen={theFen}
/>{" "}
</div>



the commented code here is the custom hook that fetches the chess object
"use client";
import { useFetchPuzzle } from "@/lib/hooks/query/fetchPuzzle";
import Button from "../ui/button";
import Image from "next/image";
import { useEffect, useState } from "react";
import PlayTemp from "./playTemp";
import ChessSession from "./chessSession";
import { useFetchUser } from "@/lib/hooks/query/fetchUser";
import { useSession } from "next-auth/react";

const GameSession = () => {
const { data: session } = useSession();

const [fetch, setFetch] = useState(false);
const user = useFetchUser(session?.user?.email);
const [game, setGame] = useState(false);
console.log("fetch in game", fetch);
// useEffect(() => {
// game
// ? (document.body.style.overflow = "hidden")
// : (document.body.style.overflow = "auto");
// }, [game]);

return (
<>
{game === false ? (
<PlayTemp setGame={setGame} user={user} />
) : (
<div className="py-28 flex md:px-40 justify-around items-center w-full ">
<ChessSession setGame={setGame} user={user} />
</div>
)}
</>
);
};

export default GameSession;
"use client";
import { useFetchPuzzle } from "@/lib/hooks/query/fetchPuzzle";
import Button from "../ui/button";
import Image from "next/image";
import { useEffect, useState } from "react";
import PlayTemp from "./playTemp";
import ChessSession from "./chessSession";
import { useFetchUser } from "@/lib/hooks/query/fetchUser";
import { useSession } from "next-auth/react";

const GameSession = () => {
const { data: session } = useSession();

const [fetch, setFetch] = useState(false);
const user = useFetchUser(session?.user?.email);
const [game, setGame] = useState(false);
console.log("fetch in game", fetch);
// useEffect(() => {
// game
// ? (document.body.style.overflow = "hidden")
// : (document.body.style.overflow = "auto");
// }, [game]);

return (
<>
{game === false ? (
<PlayTemp setGame={setGame} user={user} />
) : (
<div className="py-28 flex md:px-40 justify-around items-center w-full ">
<ChessSession setGame={setGame} user={user} />
</div>
)}
</>
);
};

export default GameSession;
Lumberjack
Lumberjack16mo ago
https://github.com/CLOG9/PuzChess here's the github repo u can check these files in chessboard.tsx , chesssession.tsx, gamesession.tsx in the component/layout folder
GitHub
GitHub - CLOG9/PuzChess: a new chess puzzles platform made with nex...
a new chess puzzles platform made with next js. Contribute to CLOG9/PuzChess development by creating an account on GitHub.
Want results from more Discord servers?
Add your server