Подходит ли этот редуктор:
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 и неизменность
@ristepan Я бы посоветовал спросить об этом у реагировать реддит. Вы можете не привлечь к этому внимание, хотя это действительно хороший вопрос. У SO много правил. Лучше пойти и спросить в более гибких местах, как я уже упоминал.
Object.assign()
копирует значения свойств. Если исходное значение является ссылкой на объект, копируется только это значение ссылки.@JuanMendes Вопрос ясен.
assign
не является глубоким клоном, поэтому вы все равно можете напрямую изменить состояние.
@ArupRakshit Есть несколько решений, это дело вкуса. Извините, но да, у SO есть свои правила, и да, существующий код в порядке, если OP не изменяет подобъекты.
Стандартный подход заключается в использовании 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
Обратите внимание, что ...
является поверхностным клоном также и может быть недостаточным.
Я думаю, что это тот же подход, я понимаю, что теперь назначение не является полной глубокой копией.
Да, я также добавил в свой ответ обновление вложенного свойства, чтобы вы могли увидеть пример того, как обновить вложенное свойство.
Если в вашем состоянии есть вложенные объекты или массивы, 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 Я думаю, что встроенный комментарий должен быть ответом.
Ответы должны быть очевидны и видны без прокрутки.
Теперь я также объяснил причину.
В конце концов, я думаю, что что-то вроде функции deepassig сделает эту работу, по крайней мере, для меня. Мне нравится библиотека immer
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.
Первый раз вижу этот поток. Вкусно!
Проверьте это: medium.com/chrisburgin/…. Он содержит больше примеров и пояснений.
Хороший! Спасибо чувак.
Мне это нравится, и я попробую
Это правильно? Насколько я могу судить, нет возвращает новое состояние, он возвращает функция нового состояния. Кроме того, он воссоздает весь объект actions
каждый раз, когда запускается функция редуктора — было бы лучше, если бы actions
определял за пределами редуктора.
Действия находятся вне редуктора. Объект просто заменяет оператор switch, функция возвращает само состояние, и доступ к объектам с точечной нотацией намного лучше, чем наличие оператора switch.
@NicolaeMaties Нет, он возвращает функцию, константа actions
определена внутри редуктора и содержит сами функции редуктора, которые работают над замыканиями, и предпочтение объектов над операторами switch-case очень субъективно.
Вы правы, ему просто нужен был звонок, я его отредактировал.
Я нашел то, что мне действительно нравится:
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) => { ... },
});
К какой части у вас есть вопрос? SO не для проверки кода