【问题标题】:Change a sigle value in an array of objects using useState in React在 React 中使用 useState 更改对象数组中的单个值
【发布时间】:2024-04-19 21:10:02
【问题描述】:

我正在学习 React 课程,我正在尝试围绕代码做一些实验以更好地理解概念。

我有一些虚拟数据:

export const data = [
  { id: 1, name: 'john' },
  { id: 2, name: 'peter' },
  { id: 3, name: 'susan' },
  { id: 4, name: 'anna' },
];

这是我的组件:

import React from "react";
import { data } from "../../../data";

const UseStateArray = () => {
  const [people, setPeople] = React.useState(data);

  return (
    <>
      {people.map((person) => {
        const { id, name } = person;
        return (
          <div key={id} className="item">
            <h4>{name}</h4>
          </div>
        );
      })}
      <button
        type="button"
        className="btn"
        onClick={() => setPeople([])}
      >
        Clear Items
      </button>
    </>
  );
};

export default UseStateArray;

该按钮在单击时有一个事件处理程序,它使用一个空数组调用 setPeople(以便删除所有元素)。

我试图更改此类按钮的功能,尝试通过以下方式更改对象(数据)数组的第一个元素的名称:

onClick={() => setPeople(people[0].name = 'Frank')}

这样做,得到一个错误,即:“TypeError: people.map is not a function”。 我认为原因是因为我不再返回数组,因此 map 无法运行。

如何简单地更改数组中存在的对象的名称(或任何值)?

【问题讨论】:

  • setPeople([{...people[0], name: "Frank"}, ...people.slice(1)])

标签: arrays reactjs object use-state


【解决方案1】:

你正在改变对象

clickHandler = () => {
   const newPeople = people.map((person, index) => {
       if (index === 0) {
            return {
                ...person,
                name: 'Frank'
            }
        }

        return person;
   });
  
   setPeople(newPeople);
}
....
....
onClick={clickHandler}

【讨论】:

    【解决方案2】:
    1. 您需要将该数组复制到较新的版本中。
    2. 使用 index 属性从数组中提取对象。
    3. 更新字段。
    function App() {
      const [data, setData] = React.useState([
        { name: "Hello", id: 1 },
        { name: "World", id: 2 }
      ]);
    
      function changeName(idx) {
        const newData = [...data];
        newData[idx].name = "*";
        setData(newData);
      }
    
      return (
        <div>
          {data.map((d, idx) => {
            return (
              <div>
                <p>{d.name}</p>
                <button
                  onClick={() => {
                    changeName(idx);
                  }}
                />
              </div>
            );
          })}
        </div>
      );
    }
    

    注意:-

    状态上不允许突变,这基本上意味着您不能直接更改状态。复制对象或数组并进行更新。

    【讨论】:

    • 好答案,我认为data[idx].name = "*"; 应该是newData[idx].name = "*";
    • 宾果游戏!已更正。
    最近更新 更多