Этот редукционный редуктор в порядке?

Подходит ли этот редуктор:

function someReducer(state = initialState, action) {
   if (action.type === SOME_ACTION) {
      const newState = Object.assign( {}, state );
      // ...
      // doing whatever I want with newState 
      // ...
      return newState;
   }   
   return state;
}

и если все в порядке, зачем нам все эти неизменяемые библиотеки, чтобы усложнить нам жизнь.

p.s. Просто пытаюсь понять Redux и неизменность

К какой части у вас есть вопрос? SO не для проверки кода

Juan Mendes 08.04.2019 16:01

@ristepan Я бы посоветовал спросить об этом у реагировать реддит. Вы можете не привлечь к этому внимание, хотя это действительно хороший вопрос. У SO много правил. Лучше пойти и спросить в более гибких местах, как я уже упоминал.

Arup Rakshit 08.04.2019 16:02
Для глубокого клонирования нам нужно использовать другие альтернативы, потому что Object.assign() копирует значения свойств. Если исходное значение является ссылкой на объект, копируется только это значение ссылки.
Rayon 08.04.2019 16:03

@JuanMendes Вопрос ясен.

Arup Rakshit 08.04.2019 16:03
assign не является глубоким клоном, поэтому вы все равно можете напрямую изменить состояние.
Dave Newton 08.04.2019 16:08

@ArupRakshit Есть несколько решений, это дело вкуса. Извините, но да, у SO есть свои правила, и да, существующий код в порядке, если OP не изменяет подобъекты.

Juan Mendes 08.04.2019 16:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
284
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Стандартный подход заключается в использовании switch/case с синтаксисом распространения (...) в редюсере.

export default function (state = initialState, action) {
  switch (action.type) {
    case constants.SOME_ACTION:
      return {
        ...state,
        newProperty: action.newProperty
      };

    case constants.ERROR_ACTION:
      return {
        ...state,
        error: action.error
      };

    case constants.MORE_DEEP_ACTION:
      return {
        ...state,
        users: {
          ...state.users,
          user1: action.users.user1
        }
      };

    default:
      return {
        ...state
      }
  }
}

Затем вы можете использовать синтаксис распространения ES6, чтобы вернуть старое состояние с любыми новыми свойствами, которые вы хотите изменить/добавить к нему.

Подробнее об этом подходе можно прочитать здесь... https://redux.js.org/recipes/using-object-spread-operator

Обратите внимание, что ... является поверхностным клоном также и может быть недостаточным.

Dave Newton 08.04.2019 16:08

Я думаю, что это тот же подход, я понимаю, что теперь назначение не является полной глубокой копией.

ristepan 08.04.2019 16:33

Да, я также добавил в свой ответ обновление вложенного свойства, чтобы вы могли увидеть пример того, как обновить вложенное свойство.

Mark 08.04.2019 16:39

Если в вашем состоянии есть вложенные объекты или массивы, Object.assign или ... скопируют ссылки на вашу старую переменную состояния, и это может вызвать некоторые проблемы. По этой причине некоторые разработчики используют неизменяемые библиотеки, поскольку в большинстве случаев состояние имеет глубоко вложенный массив или объекты.

function someReducer(state = initialState, action) {
   if (action.type === SOME_ACTION) {
       const newState = Object.assign( {}, state );
       // newState can still have references to your older state values if they are array or orobjects

      return newState;
   }   
   return state;
}

Вы просто скопировали его вопрос, здесь нет ответа.

rrd 08.04.2019 16:07

@rrd Я думаю, что встроенный комментарий должен быть ответом.

Dave Newton 08.04.2019 16:09

Ответы должны быть очевидны и видны без прокрутки.

Dave Newton 08.04.2019 16:09

Теперь я также объяснил причину.

Ashish 08.04.2019 16:11

В конце концов, я думаю, что что-то вроде функции deepassig сделает эту работу, по крайней мере, для меня. Мне нравится библиотека immer

ristepan 08.04.2019 16:28
Ответ принят как подходящий

export default function (state = initialState, action) {

  const actions = {
    SOME_ACTION: () => {
      return {
        ...state
      }
    },
    ANOTHER_ACTION: () => {
      return {
        ...state
        error: action.error
      }
    },
    DEFAULT: () => state;
  }
  
  return actions[action.type] ? actions[action.type]() : actions.DEFAULT(); 
}

Я предпочитаю делать это вместо этого. Я не большой поклонник операторов switch.

Первый раз вижу этот поток. Вкусно!

Mark 08.04.2019 16:11

Проверьте это: medium.com/chrisburgin/…. Он содержит больше примеров и пояснений.

Nicolae Maties 08.04.2019 16:13

Хороший! Спасибо чувак.

Mark 08.04.2019 16:14

Мне это нравится, и я попробую

ristepan 08.04.2019 16:18

Это правильно? Насколько я могу судить, нет возвращает новое состояние, он возвращает функция нового состояния. Кроме того, он воссоздает весь объект actions каждый раз, когда запускается функция редуктора — было бы лучше, если бы actions определял за пределами редуктора.

David 08.04.2019 16:19

Действия находятся вне редуктора. Объект просто заменяет оператор switch, функция возвращает само состояние, и доступ к объектам с точечной нотацией намного лучше, чем наличие оператора switch.

Nicolae Maties 08.04.2019 16:23

@NicolaeMaties Нет, он возвращает функцию, константа actions определена внутри редуктора и содержит сами функции редуктора, которые работают над замыканиями, и предпочтение объектов над операторами switch-case очень субъективно.

David 08.04.2019 16:28

Вы правы, ему просто нужен был звонок, я его отредактировал.

Nicolae Maties 08.04.2019 17:20

Я нашел то, что мне действительно нравится:

 import createReducer from 'redux-starter-kit';
 const someReducer = createReducer( initialState, {
    SOME_ACTION: (state) => { /* doing whatever I want with this local State */ },
    SOME_ANOTHER_ACTION: (state) => { /* doing whatever I want with local State */ },
    THIRD_ACTION: (state, action) => { ... }, 
 });

Другие вопросы по теме