react-hooks/rules-of-hooks
Unanswered
Dutch Smoushond posted this in #help-forum
Dutch SmoushondOP
"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);
5 Replies
Dutch SmoushondOP
i get the error
note that the only missing part of the code is the return(html)
./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 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 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
@Dutch Smoushond i will search for these things, thank you ❤️
Of course, glad I could help 🙂