Как изменить значения в массиве объектов с помощью onClick?

Я использую реакцию и пытаюсь редактировать объекты при нажатии кнопки. В настоящее время я отобразил 2 кнопки на странице, которые отображают их правильные значения, но при нажатии кнопки я получаю, что buttonUpgrades.map не является функцией. Функция changeButtonData может регистрировать правильные данные, но я не могу внести какие-либо изменения в данные.

Насколько я понимаю, причина, по которой отправляется ошибка, заключается в том, что buttonUpgrades является объектом, но я не знаю, как решить эту проблему.

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;

Изменить: решение, если кто-нибудь столкнется с этим:

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


person JordanSteele96    schedule 27.03.2021    source источник


Ответы (2)


Во-первых, ваш updateButtonUpgrades настроен неправильно.

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

пытается отобразить buttonUpgrades в возврате компонента, но у вас есть распространяется с синтаксисом ... в вашем вызове функции updateButtonUpgrades, так что все, что вы делаете, это передача элементов массива в функцию вместо добавления элемента в массив. Именно здесь вы получаете сообщение buttonUpgrades.map не является функциональной ошибкой. Чтобы это исправить, нужно настроить так:

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

с синтаксисом распространения INSIDE массива. Но теперь все, что вы делаете, это добавляете новое имя в массив, который выглядит так:

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

Отсюда:

  • Если вы хотите добавить объект, вы должны сделать это так:
updateButtonUpgrades([...buttonUpgrades, { name: "new name", cost, damage }]);
person jharris711    schedule 27.03.2021

Я предлагаю вам переписать функцию обратного вызова onClick: сначала создайте новые объекты с нужными атрибутами, сгруппируйте их в массив, а затем обновите состояние реакции с помощью этого нового массива.

РЕДАКТИРОВАТЬ: jharris711 дает чистую реализацию этой концепции, отличная работа!

person LeonMueller - OneAndOnly    schedule 27.03.2021