skip to Main Content

I’m getting this error:
The fix was that I needed to change state differently- the way I was updating state for my player and dealer hand was wrong.
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app"

And am struggling to understand why, as useEffect is being used within my react component

Here are the atom definitions:

import { atom } from "jotai";

export const playerHandAtom = atom([]);
export const dealerHandAtom = atom([]);

I’ve combined all the code into one file for the sake of this question but the dealer functions will all be in a file dealer.js and be imported, but even when in the same component, I’m still getting the same issue. I’m not sure if it’s a duplicate version of React issue?

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>
  );
};

I tried downgrading my dependencies as it said mismatched versions could be the issue as well, but that didn’t work and I want to keep it at React 18 or higher because I’m using createRoot.
Here are my current dependencies: 18.2.0 was recommended as it wasn’t the most recent, but I’m still getting the same error.

"jotai": "^2.8.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "^6.23.0"

Thanks all

2

Answers


  1. I would attempt pinning both versions to "18.2.0" without using the ^ sign, 18.3.1 is quite recent and there might be some patches coming soon

    "react": "18.2.0",
    "react-dom": "18.2.0",
    
    Login or Signup to reply.
  2. 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();
      }, []);
    
      // ...
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search