1

I'm using react and trying to edit objects when a button is pressed. Currently, I have rendered 2 buttons on the page that display their correct values, but when the button is pressed I get "buttonUpgrades.map is not a function". The changeButtonData function can log the correct data but I cant seem to make any changes to the data.

From my understanding the reason this is sending an error is that buttonUpgrades is an object, but I don't know how to solve the issue.

import React, { useState } from "react";
const UpgradeButton = () => {
    const [buttonUpgrades, updateButtonUpgrades] = useState([
    {
      id:0,
      name: "Upgrade one",
      cost: 5,
      amount: 0,
      damage: 1,
      damageGrowth: 1.1,
    },
    {
      id:1,
      name: "Upgrade two",
      cost: 6,
      amount: 0,
      damage: 2,
      damageGrowth: 1.2,
    },
  ]);

  const changeButtonData = (data) => {
    let {name,cost,damage} = data;
    updateButtonUpgrades(...buttonUpgrades, name="new name") // this wont let me change the value that has been assigned
    console.log(name) // this logs the name assigned to the button 
  }

  return(  
    buttonUpgrades.map((upgrade)=>
    <button key={upgrade.id}onClick={()=>changeButtonData(upgrade)}>
      <h1>Cost:{upgrade.name}</h1>
      <h1>Cost:{upgrade.cost}</h1>
      <h1>Damage:{upgrade.damage}</h1>
    </button>
    )
  )
}
export default UpgradeButton;

Edit: Solution incase anyone comes across this:

  const changeButtonData  = (data)=>{
    const {id,name,cost,amount,damage,damageGrowth} = data;
    updateButtonUpgrades(buttonUpgrades.map(buttonProps=>(buttonProps.id===id ? {...buttonProps,damage:damage * damageGrowth}:buttonProps)))
  }

2 Answers2

2

First, your updateButtonUpgrades isn't set up properly.

updateButtonUpgrades(...buttonUpgrades, name="new name")

is trying to map out the buttonUpgrades in the component's return, but you have it spread with the ... syntax in your updateButtonUpgrades function call, so all you're doing is passing the items in the array to the function instead of adding an item to the array. That is where you get the buttonUpgrades.map is not a function error from. To fix that, it should be set up like this:

updateButtonUpgrades([...buttonUpgrades, (name = "new name")])

with the spread syntax INSIDE of an array. But now, all you're doing is adding "new name" to the array, which looks like this:

[
  {id: 0, name: "Upgrade one", cost: 5, amount: 0…},
  {id: 1, name: "Upgrade two", cost: 6, amount: 0…},
  "new name"
]

From here:

  • If you want to add an object, you would do it like so:
updateButtonUpgrades([...buttonUpgrades, { name: "new name", cost, damage }]);
jharris711
  • 552
  • 3
  • 22
1

I suggest you to rewrite your onClick-callback-function: first create the new objects with the desired attributed, group them in an array and then update the react state with this new array.

EDIT: jharris711 gives a clean implementation of this concept, great work!