szemeg
szemeg

Reputation: 51

useState - Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

I got this infinite loop error. I want to change the state of isDisabled based on the value of count. How should I solve this, if I want to keep the state in hook?

const TheGame = () => { 
  const [count, setCount] = useState(0);
  const [isDisabled, setIsDisabled] = useState(false);

  const onHitHandler = async () => {
    let card = await fetchCard();

    if (card[0].value === 'ACE')
      setCount((prevCount) => prevCount + 11);
    else if (card[0].value === 'JACK' || card[0].value === 'QUEEN') || card[0].value === 'KING')
      setCount((prevCount) => prevCount + 10);
    else
      setCount((prevCount) => prevCount + Number(card[0].value));
  };

  if(count > 21)
    setIsDisabled(true);  // error occures here.

  return(something);
};

Upvotes: 0

Views: 147

Answers (2)

Colin D
Colin D

Reputation: 3119

Instead of using a useEffect, an alternative approach is to realize that this variable is not necessarily intrinsic state, but something that can be "computed" from the intrinsic state.

For example, your code could say

const TheGame = () => { 
  const [count, setCount] = useState(0);

  const onHitHandler = async () => {
    let card = await fetchCard();

    if (card[0].value === 'ACE')
      setCount((prevCount) => prevCount + 11);
    else if (card[0].value === 'JACK' || card[0].value === 'QUEEN') || card[0].value === 'KING')
      setCount((prevCount) => prevCount + 10);
    else
      setCount((prevCount) => prevCount + Number(card[0].value));
  };

  const disabled = count > 21 ? true : false // or simply const disabled = count>21

  return disabled ? <DisabledState/> : <NonDisabledState/>
};

Also, the reason why it fails when in the previous case is you do not want to use a "setState" type callback inside the normal "rendering" of your component. That is because any time a setState callback is used, it will produce a re-render of your component (so that the new state can be drawn on the screen!)

Upvotes: 0

Nokwiw
Nokwiw

Reputation: 396

Try this :

useEffect(()=>{
  if(count > 21) {
    setIsDisabled(true); 
  }
}, [count])

Upvotes: 1

Related Questions