我收到此错误: 解决方法是我需要以不同的方式更改状态 - 我更新玩家和庄家手牌状态的方式是错误的。 未捕获的错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。发生这种情况可能是由于以下原因之一:
我很难理解为什么,因为
useEffect
正在我的反应组件中使用
以下是原子定义:
import { atom } from "jotai";
export const playerHandAtom = atom([]);
export const dealerHandAtom = atom([]);
为了解决这个问题,我已将所有代码合并到一个文件中,但经销商功能将全部位于文件 Dealer.js 中并导入,但即使在同一组件中,我仍然遇到相同的问题。我不确定这是否是 React 问题的重复版本?
import React, { useEffect } from "react";
import { createRoot } from "react-dom/client";
import { useAtom } from "jotai";
import { playerHandAtom, dealerHandAtom } from "./atoms";
import board from "./img/table_with_chips.png";
const BlackJack = () => {
const [dealerHand, setDealerHand] = useAtom(dealerHandAtom);
const [playerHand, setPlayerHand] = useAtom(playerHandAtom);
const deck = [
["2", 2],
["3", 3],
["4", 4],
["5", 5],
["6", 6],
["7", 7],
["8", 8],
["9", 9],
["10", 10],
["jack", 10],
["queen", 10],
["king", 10],
["ace", 11],
];
const dealCard = (hand) => {
const random = Math.floor(Math.random() * deck.length);
hand.push(deck[random][0]);
};
const dealHand = () => {
const tempPlayHand = [];
const tempDealHand = [];
dealCard(tempPlayHand);
dealCard(tempPlayHand);
dealCard(tempDealHand);
dealCard(tempDealHand);
setPlayerHand(tempPlayHand);
setDealerHand(tempDealHand);
};
useEffect(() => {
dealHand();
}, []);
return (
<div id="game-container">
<img id="game-board" alt="Green Blackjack poker table" src={board} />
</div>
);
};
我尝试降级我的依赖项,因为它说版本不匹配也可能是问题所在,但这不起作用,我想将其保留在 React 18 或更高版本,因为我正在使用 createRoot。 以下是我当前的依赖项:建议使用 18.2.0,因为它不是最新的,但我仍然遇到相同的错误。
"jotai": "^2.8.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "^6.23.0"
谢谢大家
const BlackJack = () => {
const [dealerHand, setDealerHand] = useAtom(dealerHandAtom);
const [playerHand, setPlayerHand] = useAtom(playerHandAtom);
const dealCard = (hand) => {
const random = Math.floor(Math.random() * deck.length);
hand.push(deck[random][0]);
};
const dealHand = () => {
// ❌ don't call useAtom here again
// ❌ this function already has access to it
dealCard(playerHand);
dealCard(playerHand);
dealCard(dealerHand);
dealCard(dealerHand);
};
useEffect(() => {
dealHand();
}, []);
// ...
};
我会尝试将两个版本固定为“18.2.0”而不使用 ^ 符号,18.3.1 是最近的版本,可能很快就会有一些补丁
"react": "18.2.0",
"react-dom": "18.2.0",
基本上你不能/不应该在其他钩子中调用钩子,这违反了钩子法则 -> React Hook Rules
这是因为它通常会导致无限的重新渲染等。
我一般不熟悉 Atom 或状态管理器,但您能否显示playerHandAtom 和dealerHandAtom 的代码?这样我们就能为您提供更多帮助。
但通常解决方案很可能是重构代码以允许在 useEffect 中使用它。