Изменение значения sigle в массиве объектов с помощью useState в React

#arrays #reactjs #object #use-state

#массивы #reactjs #объект #use-state

Вопрос:

Я следую курсу 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 не является функцией».
Я думаю, причина в том, что я больше не возвращаю массив и поэтому map не удается запустить.

Как я могу просто изменить имя (или любое значение) объекта, присутствующего в массиве?

Комментарии:

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

Ответ №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 = "StackOverFlow";
    setData(newData);
  }

  return (
    <div>
      {data.map((d, idx) => {
        return (
          <div>
            <p>{d.name}</p>
            <button
              onClick={() => {
                changeName(idx);
              }}
            />
          </div>
        );
      })}
    </div>
  );
}
  

ПРИМЕЧАНИЕ :-

Мутация не разрешена для состояния, что в основном означает, что вы не можете изменить состояние напрямую. Скопируйте объект или массив и выполните обновления.

Комментарии:

1. Хороший ответ, я думаю data[idx].name = "StackOverFlow"; , должен быть newData[idx].name = "StackOverFlow";

2. Бинго! Исправлено.