Рассмотрим это простое приложение Redux:
const items = (state = [], action) => {
switch (action.type) {
case "ADD_ITEMS":
return addItems(state, action.items)
case "REMOVE_ITEMS":
return removeItems(state, action.items)
default:
return state
}
}
const page = (state = 1, action) => {
switch (action.type) {
case "PREVIOUS":
return state - 1
case "NEXT":
return state + 1
default:
return state
}
}
const reducer = combineReducers({ items, page })
Как видно, состояние состоит из двух частей:
items
: список элементов.Элементы могут быть добавлены и удалены из списка. page
: текущая страница системы нумерации страниц в пользовательском интерфейсе.Допустим, одновременно должно отображаться десять элементов, и пользователь может перемещаться между страницами.
Пользовательский интерфейс отображается с помощью Redux:
const mapStateToProps = (state) => {
const start = (state.page - 1) * 10
const stop = state.page * 10 - 1
return {
visibleItems: state.items.splice(start, stop)
}
}
В настоящее время это приложение имеетошибка.Если пользователь находится на пятой странице и все элементы, кроме одиннадцати, удалены, page
внезапно будет иметь недопустимое значение.Больше нет пятой страницы, только первая и вторая страницы!Желаемое поведение состоит в том, что он должен измениться на две, наивысшую допустимую страницу.
Я мог бы справиться с этой ситуацией, добавив case "REMOVE_ITEMS"
к редуктору page
.Но page
не знает, каким будет новое значение items.length
.Чтобы он знал, что ему потребуется доступ к состоянию items
, а затем пересчитать результат removeItems
.Для меня это не похоже на хороший дизайн.
Другой вариант - написать один редуктор, но он будет довольно запутанным, и я не решаюсь объединить эти куски кода с отдельными задачами.
Как лучше всего справиться с такой ситуацией?