@mk11

Почему не происходит перерисовка при изменении объекта?

Есть объект store и функция изменения isClicked:
export const store = {
    items: [
      {
        id: 1,
        isClicked: false,
      },
      {
        id: 2,
        isClicked: false,
      }
    ],
  };

export function changeClikced(id) {
    const getItem = store.items.find(item => item.id == id);
    if (getItem) getItem.isClicked = true;
}


Есть компонент App:
function App() {
  const [items, setItems] = useState(store.items);

  const catchPokemon = (id) => () => {
    changeClikced(id)
    console.log(items)
  }

  return (
    <>
      {items.map((item) => (
        <button onClick={catchPokemon(item.id)} key={item.id}>
          {!item.isClicked ? 'Нажать' : 'Уже была нажата' }
        </button>    
      ))}
    </>
  );
}


При нажатии на кнопку isClicked меняться, но компонент не перерисовывается. Можно ли заставить кнопки изменять свой текст при клике?
  • Вопрос задан
  • 103 просмотра
Решения вопроса 3
@historydev
Информационный наркоман
Alexandroppolus
@Alexandroppolus
кодир
У тебя объект store - не наблюдаемый. Хочешь его сделать наблюдаемым, натрави на него mobx.

А если на голом Реакте, то надо делать изменения через setItems, примерно так
setItems((prev) => {
  const i = prev.findIndex(item => item.id === id);
  if (i < 0 || prev[i].isClicked) {
    return prev;
  }
  const newArr = [...prev];
  newArr[i] = {...prev[i], isClicked: true};
  return newArr;
});
Ответ написан
Комментировать
alexey-m-ukolov
@alexey-m-ukolov Куратор тега React
Отвечу на вопрос почему.
Причины две:
1. При старте вы сохраняете копию массива в локальный стейт и дальше работаете с ней.
2. Даже если бы вы этого не делали, а итерировали по оригинальному массиву, всё равно бы не работало как вы ожидаете, потому что вы мутируете внутреннее состояние объекта, а Реакт в него не смотрит и запускает перерегдер только тогда, когда меняется ссылка на сам объект.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы