useState Invalid Hook Call

Hello everyone!

I’ve run into a problem using the useState hook, which I’m still pretty new to using. I have successfully used it in one case on this project but upon adding another later I am getting the Invalid Hook Call error. I believe I have added it correctly, and even when deleting the sections of code that involve this instance of useState are deleted, I receive the same error. You can see the individual function below, or the entire app on GitHub here.

Thanks for any help!

let GameData = (passedData) => {
  
  const [currentAbility, setAbility] = useState('')
  
  let data = passedData.data;
  
  let capitalize = (target) => {
    let capitalized;
    capitalized = target[0].toUpperCase() + target.slice(1);
    if (capitalized.includes("-")) {
      capitalized = capitalized.split("-").map(i => i[0].toUpperCase() + i.slice(1)).join(" ")
    }
    if (capitalized.length===2) {
      capitalized = capitalized.split("").map(i => i[0].toUpperCase()).join("")
    }
    return capitalized
  }

  let pokemonTypes = passedData.data.types.map((type)=>type.type.name)
  let weaknessCalc = (targetTypes) => {
    let weaknesses  = {}

    targetTypes.forEach((type) => {
      let target = typesList[type];
      let weak = target.weak;
      let resistant = target.resistant;
      let immune = target.immune;
      weak.forEach((type)=>{
        if (weaknesses.hasOwnProperty(type)) {
          weaknesses[type] = weaknesses[type] * 2;
          if (weaknesses[type]===1) {
            delete weaknesses[type]
          }
        } else {
          weaknesses[type] = 2;
        }
      })
      resistant.forEach((type)=>{
        if (weaknesses.hasOwnProperty(type)) {
          weaknesses[type] = weaknesses[type] * .5;
          if (weaknesses[type]===1) {
            delete weaknesses[type]
          }
        } else {
          weaknesses[type] = .5;
        }
      })
      immune.forEach((type)=>{
        if (weaknesses.hasOwnProperty(type)) {
          weaknesses[type] = weaknesses[type] * 0;
          if (weaknesses[type]===1) {
            delete weaknesses[type]
          }
        } else {
          weaknesses[type] = 0;
        }
      })
    })
    
    return weaknesses
  }
    let entries = Object.entries(weaknessCalc(pokemonTypes))
    entries.sort(([a, b],[c, d]) => d - b)
    let weaknessMap = entries.map((element) => {
      return <div id="weaknessMap"><span className={element[0]}>{`${capitalize(element[0])}`}</span>-type damage is {element[1]}x. </div>
    })

    let hiddenDisplay = (passedAbility) => {
      return (!passedAbility["is_hidden"]) ? passedAbility.ability.name : `${passedAbility.ability.name} (Hidden Ability)`
    }


    let abilityFunction = async (abilityName) => {
      try {
        const res = await fetch(`https://pokeapi.co/api/v2/ability/${abilityName}/`);
        const data = await res.json();
        return data["effect_entries"][0]["short_effect"] 
      } catch (err) {
        return "error"
      }
    }

    let statTotal = (passedData) => {
      let total = 0;
      passedData.stats.forEach(stat=>{
        total+=stat["base_stat"]
      })
      return total
    }

    return (
     <div>
       <h2>Type Effectiveness</h2>
       {weaknessMap}
       <p>All other damage types are 1x.</p>
       <h2>Abilities</h2>
       {data.abilities.map(ability=>{
        return <p className="tooltip" onMouseEnter={()=>setAbility(abilityFunction(ability.ability.name))}>{capitalize(hiddenDisplay(ability))}
        <span className="tooltipText">{currentAbility ? currentAbility : "Loading..."}</span>
        </p>
       })}
       <h2>Base Stats</h2>
       <table id="statsTable" className="statsTable">
       {data.stats.map(stat=>{
         return <tr>
           <td className="statsTable">{capitalize(stat.stat.name)}</td>
           <td className="statsTable">{stat["base_stat"]}</td>
           </tr>
       })}
       <tr>
       <td>Total</td>
       <td>{statTotal(data)}</td>
       </tr>
       </table>
       </div>
      
    )
  
}

Can you console.log(data[“effect_entries”][0][“short_effect”]) at line 228
Can you do a console.log(ability) on line 249

Also do you have a live version to check?

I don’t have a live version, but even if I remove the abilityFunction function, onMouseEnter event, and the currentAbility variable call, leaving just the const [currentAbility, setAbility] = useState(’’) declaration, this alone causes the error.

is that (’’)the exact character you are using in your code? That’s why you are getting the error

Oh really? I was wanting to have it start with no value. Is there a way to do this?

you can just leave it empty

[currentAbility, setAbility] = useState()

Okay! I’ll leave it blank, however that has not solved the error unfortunately.

Hello!

The problem is in this line:

<div className="tab" onClick={()=>setDisplay(GameData(data))}>Game Data</div>

Check the rest of your code and compare the difference between using a component and its props and how you call a function. Is GameData a component or a function?

Another hint: You used it correctly just the line before the one I mentioned.

1 Like

Thank you very much! Changing this has fixed that problem. I guess I thought that Class components and Function components had to be passed differently. Thank you so much for taking the time to look and help me!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.