Почему объекты в Redux должны быть неизменными?
Почему объекты в Redux должны быть неизменными? Я знаю, что некоторые фреймворки, такие как Angular2, будут использовать onPush и могут использовать преимущества неизменяемости для сравнения состояний представлений для более быстрого рендеринга, но мне интересно, есть ли другие причины, так как Redux не зависит от фреймворка и все же упоминает в своих собственных документах использовать неизменность (независимо от рамок).
Ценю любые отзывы.
5 ответов
Redux - это небольшая библиотека, которая представляет состояние как (неизменяемые) объекты. И новые состояния, передавая текущее состояние через чистые функции для создания совершенно новых состояний объекта / приложения.
Если ваши глаза застеклены, не волнуйтесь. Подводя итог, можно сказать, что Redux не представляет изменений в состоянии вашего приложения путем изменения объектов (как вы это сделали бы с объектно-ориентированными парадигмами). Вместо этого изменения состояния представляются как разница между входным объектом и выходным объектом (var output = reducer(input)
). Если вы измените либо input
или же output
Вы лишаете законной силы государство.
Подводя итог, можно сказать, что неизменность является требованием Redux, потому что Redux представляет состояние вашего приложения в виде "моментальных снимков замороженных объектов". С помощью этих дискретных снимков вы можете сохранить свое состояние или изменить его состояние и, как правило, иметь больше "учета" всех изменений состояния.
Состояние вашего приложения изменяется только категорией чистых функций, называемых редукторами. Редукторы имеют 2 важных свойства:
- Ониникогда не видоизменяются, возвращая вновь построенные объекты: это позволяет рассуждать о входе + выходе без побочных эффектов
- Их подписьвсегда
function name(state, action) {}
так что их легко составить:
Предположим, что состояние выглядит так:
var theState = {
_2ndLevel: {
count: 0
}
}
Мы хотим увеличить счет, поэтому мы делаем эти редукторы
const INCR_2ND_LEVEL_COUNT = 'incr2NdLevelCount';
function _2ndlevel (state, action) {
switch (action.type) {
case INCR_2ND_LEVEL_COUNT:
var newState = Objectd.assign({}, state);
newState.count++
return newState;
}
}
function topLevel (state, action) {
switch (action.type) {
case INCR_2ND_LEVEL_COUNT:
return Objectd.assign({}, {_2ndLevel: _2ndlevel(state._2ndlevel)});
}
}
Обратите внимание на использованиеObjectd.assign({}, ...)
создать совершенно новые объекты вкаждом редукторе:
Предполагая, что мы подключили Redux к этим редукторам, тогда, если мы используем систему событий Redux для запуска изменения состояния...
dispatch({type: INCR_2ND_LEVEL_COUNT})
... Redux позвонит:
theNewState = topLevel(theState, action);
НОТА:action
изdispatch()
СейчасtheNewState
этосовершенно новый объект.
Примечание. Вы можете установить неизменность с помощью библиотеки (или новых языковых функций) или просто быть осторожным, чтобы ничего не изменять:D
Для более глубокого взгляда я настоятельно рекомендую вам посмотреть это видео Дана Абрамова (создателя). Он должен ответить на все ваши давние вопросы.
Следующие преимущества неизменяемости упомянуты в документации Redux:
- И Redux, и React-Redux используют поверхностную проверку на равенство. Особенно:
- Утилита объединения Redux в Redux поверхностно проверяет изменения ссылок, вызванные вызываемыми редукторами.
- Метод подключения React-Redux генерирует компоненты, которые неглубоко проверяют изменения ссылок на корневое состояние, а также возвращают значения из функции mapStateToProps, чтобы увидеть, действительно ли обернутые компоненты необходимо повторно визуализировать. Такая мелкая проверка требует неизменности для правильного функционирования.
- Неизменное управление данными в конечном итоге делает обработку данных более безопасной.
- Отладка во времени требует, чтобы редукторы были чистыми функциями без побочных эффектов, чтобы вы могли правильно переключаться между различными состояниями.
Основная причина, по которой Redux использует неизменяемость, заключается в том, что ему не нужно перемещаться по дереву объектов, чтобы проверить изменения в каждом значении ключа. Вместо этого он только проверяет, была ли ссылка на объект изменена или нет, чтобы обновить DOM при изменении состояния.
Большая статья https://medium.cobeisfresh.com/how-redux-can-make-you-a-better-developer-30a094d5e3ec
Наряду с неизменяемыми данными, чистые функции являются одной из основных концепций функционального программирования.
На основании официальных документов:
Есть несколько причин, по которым вы не должны изменять состояние в Redux:
- Это вызывает ошибки, такие как пользовательский интерфейс, который не обновляется должным образом, чтобы отображать последние значения.
- Это затрудняет понимание того, почему и как было обновлено состояние.
- Это усложняет написание тестов
- Это нарушает возможность правильного использования «отладки во времени».
- Это противоречит предполагаемому духу и моделям использования Redux.