Является ли этот редуктор redux в порядке

#javascript #reactjs #redux #immutability

#javascript #reactjs #redux #неизменность

Вопрос:

В порядке ли этот редуктор:

 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 и неизменность

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

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

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

3. Для глубокого клонирования нам нужно использовать другие альтернативы, потому что Object.assign() копирует значения свойств. Если исходное значение является ссылкой на объект, оно копирует только это ссылочное значение.

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

5. assign это не глубокий клон, поэтому вы все равно можете войти и напрямую изменить состояние.

Ответ №1:

 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.

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

1. Впервые вижу этот поток. Вкусно!

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

3. Приятно! Спасибо, чувак.

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

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

Ответ №2:

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

 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

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

1. Отметим, что ... это также мелкий клон, и его может быть недостаточно.

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

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

Ответ №3:

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

  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) => { ... }, 
 });
  

Ответ №4:

Если в вашем состоянии есть вложенные объекты или массивы, 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;
}
  

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

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

2. @rrd Я думаю, что встроенный комментарий предназначен для ответа.

3. Ответы должны быть очевидными и видимыми без hscrolling.

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

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