"use client";
import { useRouter } from "next/navigation";
import React, { useEffect, useState } from "react";
export default function Game(props: { params: Promise<{ id: string }> }) {
const params = React.use(props.params);
const [moves, setMoves] = useState<number[]>([]);
const [message, setMessage] = useState<string>();
const [isEnd, setEnd] = useState(false);
const router = useRouter();
const board: string[] = " ".split("");
for (let i = 0; i < moves.length; i++) {
board[moves[i] - 1] = (i % 2 == 0 ? "X" : "O");
}
useEffect(() => {
const fetchData = async () => {
const game = await fetch("/api/getGame", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: params.id,
}),
}).then((e) => e.json());
if(game.message == "Invalid game id"){
setMessage(game.message);
setEnd(true);
return;
}
setMoves(game.message.moves || []);
if(game.message.result != null){
setEnd(true);
setMessage(game.message.result);
}
};
fetchData();
}, [params.id]);
async function clickHandler(num: number) {
await fetch("/api/move", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: params.id,
move: num,
}),
})
.then(async (e) => {
const res = await e.json();
if (e.status != 200) throw new Error(res.message);
setMoves(res.message.moves || []);
setMessage(res.message.result || "");
if (res.message.result != null) {
setEnd(true);
}
})
.catch((error) => {
console.log(error.text);
setMessage(error.message);
});
}
console.log(params.id);
#react-hooks/rules-of-hooks
6 messages · Page 1 of 1 (latest)
🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord
🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize
✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)
i get the error
./app/[id]/page.tsx
8:29 Error: React Hook "useState" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
9:33 Error: React Hook "useState" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
10:27 Error: React Hook "useState" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
11:18 Error: React Hook "useRouter" may be executed more than once. Possibly because it is called in a loop. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
info - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/app/api-reference/config/eslint#disabling-rules
note that the only missing part of the code is the return(html)
First of all you should try not to setState inside an effect for many reasons, this being one of them.
The only valid place to setState in an Effect is in the promise callback
Like this, this is a simple example:
fetch(…).then(res => res.json() ).then( game => {
if (game.whatever){
setState(game)
}
…. // your other code
})
Not like this
const game = await fetch().then( res => res.json() )
if (game.whatever ) {
setState( game )
// …. your other code
}
The logic where you’re setting state should be inside the promise callback.
I would recommend you using a library like React Query to handle async queries and mutations, it’s much cleaner and helps a lot with other stuff that I didn’t even mentioned (race conditions, caching, clean ups..)
If you’re trying to build a game with react, game are made up with lots of states, so a state management library like Zustand or xState/store can definitely help you
I made a 2D web game for a class a couple months ago, I used react, but all the game state was managed with Zustand
i will search for these things, thank you ❤️