Задать вопрос

Почему редюсер вызывается два раза?

Есть простенький проект списка дел: https://codesandbox.io/s/romantic-darkness-p18wh

Проблема следующая: при удалении элемента из списка дел редюсер с action.type равным 'DELETE_TODO' почему-то вызывается два раза. Важно уточнить, что это происходит только после добавления нового элемента, то есть если изначально обновить страницу и ничего не добавляя нажать на "удалить" - редюсер вызывается единожды.
Судя по консоль логам, компонент из которого отправляется действие удаления в повторном рендере не участвует, то есть редюсер запускается будто "из воздуха". Стейт todos (в котором хранятся элементы) судя по логам не изменяется, то есть тоже по идее не виноват.
Также важно уточнить, что с action.type равным 'ADD_TODO' такой проблемы нет от слова совсем, НО! если код из 'ADD_TODO' вставить в 'DELETE_TODO' (подогнав значения переменных) то проблема сохраняется. Будто любое действие кроме 'ADD_TODO' заранее проклято.
В случае с 'DELETE_TODO' вся эта котовасия проблем не создает, ибо все хорошо удаляется, но при создании функции отметки дела галочкой двойной вызов редюсера приводит понятно к чему - элемент помечается выполненным и тут же помечается обратно. То есть так оно работать не должно.
Хотелось бы чтобы знающие люди объяснили принцип этой странной "фичи" реакта и помогли найти решение.
Также интересно было бы узнать почему в принципе оба моих контекста рендерятся два раза при взаимодействии с ними (и даже при первоначальной загрузке, я все отметил логами), и что является причиной двойного рендера компонента AddForm.js при каком-либо взаимодействии с ним (набор текста, нажатия на кнопки и т.д). Заранее огромное спасибо.
  • Вопрос задан
  • 120 просмотров
Подписаться 2 Сложный Комментировать
Решения вопроса 1
@paoluccio
но при создании функции отметки дела галочкой...

у вас там ошибка, вы мутируете todo, что не есть хорошо...

Должно быть:
export const todoReducer = (state, action) => {
  switch (action.type) {
    // ...
    case "MARK_TODO":
      const newState = state.map(todo => {
        if (todo.id === action.id) {
          return { ...todo, status: !todo.status };
        }
        return todo;
      });
      return newState;
    // ...
  }
};


...запускается будто "из воздуха".

Будто любое действие кроме 'ADD_TODO' заранее проклято.


Имя злодею - Strict Mode. Почитать можно тут.

Если сильно раздражает - идёте в index.js и убираете обёртку над <App />.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы