Ответ
Reducer (редюсер) в Redux — это чистая функция, которая определяет, как состояние (state) приложения изменяется в ответ на отправленное действие (action). Это единственное место, где логика обновления состояния должна быть описана.
Сигнатура функции:
function reducer(previousState, action) {
// Вычисляем и возвращаем следующее состояние
return nextState;
}
Три фундаментальных принципа Reducer:
- Чистота: Не производит сайд-эффектов (вызовов API, мутаций).
- Иммутабельность: Не изменяет переданный
previousState. Вместо этого создаёт и возвращает новый объект состояния. - Детерминированность: Для одних и тех же входных
stateиactionвсегда возвращает одинаковыйnextState.
Практический пример из моего опыта: Допустим, у нас есть состояние для управления списком задач (todo list).
// Начальное состояние
const initialState = {
todos: [],
filter: 'SHOW_ALL'
};
// Reducer
function todoApp(state = initialState, action) {
switch (action.type) {
case 'ADD_TODO':
// ВАЖНО: Не мутируем старый массив, создаём новый
return {
...state, // Копируем все поля предыдущего состояния
todos: [
...state.todos, // Копируем старый массив todos
{ // Добавляем новый элемент
id: action.payload.id,
text: action.payload.text,
completed: false
}
]
};
case 'TOGGLE_TODO':
return {
...state,
todos: state.todos.map(todo =>
// Если это не тот todo, возвращаем как есть
todo.id !== action.payload.id ? todo :
// Иначе создаём новый объект todo с изменённым полем
{ ...todo, completed: !todo.completed }
)
};
case 'SET_FILTER':
return {
...state,
filter: action.payload.filter
};
// На действие по умолчанию возвращаем неизменённое состояние
default:
return state;
}
}
Почему это важно: Такая архитектура делает изменения состояния предсказуемыми и легко тестируемыми. Вы можете логировать каждое действие и состояние «до/после», что неоценимо при отладке сложного взаимодействия в приложении.