Во втором редукторе вы получаете данные из импорта cats
, а не из состояния! Таким образом, ваше сокращение всегда возвращает объект из импорта, а не из какого-либо состояния, в которое оно передано. Не следует импортировать cats
в код редуктора.
Аналогично, в вашем первом редукторе вы возвращаете данные из импорта кошек.
В обоих случаях вы должны возвращать данные из переданного параметра state
, а не из cats
import.
Ваш первый редуктор будет выглядеть так:
export default (state = cats, action) => {
switch(action.type) {
case 'INCREMENT':
return state.map(cat => cat.name === action.name ? {...cat, clickCount: cat.clickCount + 1} : {...cat});
default:
return state;
}
}
Второй редуктор:
export default (state = cats[0], action) => {
switch(action.type) {
case 'SET_CURRENT_CAT':
return {...state.filter(cat => cat.name === action.name)[0]};
default:
return state;
}
}
Обратите внимание, что код корпуса редуктора относится к state
, а не cats
.
Также обратите внимание, что редукторы теперь возвращают новые объекты, которые являются клонами объектов в состоянии (НЕ исходные объекты), используя оператор распространения объектов: {...cat}
и {...state.filter()[0]}
.
Не обязательно импортировать cats
и использовать его по умолчанию, хотя это не лучший дизайн. (Проблема в том, что код вообще не использует параметр состояния, а вместо этого использует импортированную коллекцию объектов.) Чтобы избежать полного использования импорта котов в редукторах, можно передать их как содержимое хранилища по умолчанию. до createStore
:
import cats from '../cats';
const defaultState = { cats, currentCatName: 'Lucy' };
const store = createStore(
rootReducer,
defaultState
);
Тогда значения по умолчанию для параметров редуктора должны возвращать пустой массив для первого редуктора:
export default (state = [], action) => {
и пустой объект для второго редуктора:
export default (state = {}, action) => {
Другой альтернативой является добавление действия LOAD_CATS
, которое заполняет вашу коллекцию кошек, возможно, отправлено на componentDidMount для компонента приложения верхнего уровня.
Другая оптимизация, которая поможет избежать использования существующих объектов, заключается в изменении SET_CURRENT_CAT, чтобы просто изменить имя / идентификатор кошки, сохраненные в состоянии:
export default (state, action) => {
switch(action.type) {
case 'SET_CURRENT_CAT':
return action.name;
Затем, чтобы получить текущего кота, вы можете добавить селектор, который получает кота по имени / идентификатору из состояния, возвращаемого первым редуктором. (Добавление поля id поможет вам справиться со сценарием, в котором есть несколько кошек с одинаковым именем.) Селектор может выглядеть следующим образом:
function getCatByName(state, name) { return state.cats.filter(cat => cat.name === name) }