@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 меняться, но компонент не перерисовывается. Можно ли заставить кнопки изменять свой текст при клике?
  • Вопрос задан
  • 85 просмотров
Решения вопроса 3
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. Даже если бы вы этого не делали, а итерировали по оригинальному массиву, всё равно бы не работало как вы ожидаете, потому что вы мутируете внутреннее состояние объекта, а Реакт в него не смотрит и запускает перерегдер только тогда, когда меняется ссылка на сам объект.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
Else Ростов-на-Дону
от 150 000 до 200 000 ₽
OWNR SOLUTIONS Нижний Новгород
от 150 000 до 250 000 ₽