← Назад к вопросам

Хранятся ли вместе action и reducer в Redux

1.6 Junior🔥 171 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Вопрос о совместном хранении action и reducer в Redux

Краткий ответ: Нет, в классической архитектуре Redux action (действия) и reducer (редьюсеры) обычно хранятся отдельно, хотя современные подходы (как Redux Toolkit) позволяют объединять их логику в одном файле.

Разделение ответственности в Redux

В Redux чётко разделены три ключевые концепции:

  • Action — простой объект, описывающий что произошло. Содержит обязательное поле type и опционально payload.
  • Reducer — чистая функция, которая определяет как состояние меняется в ответ на action.
  • Store — единый централизованный объект состояния приложения.

Такое разделение соответствует принципу единой направленности данных (unidirectional data flow) и упрощает отладку, тестирование и понимание потока данных.

Пример классического разделения

// actions.js – файл с action creators
export const ADD_TODO = 'ADD_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO';

export const addTodo = (text) => ({
  type: ADD_TODO,
  payload: { text }
});

// reducers.js – файл с reducer
import { ADD_TODO, TOGGLE_TODO } from './actions';

const initialState = {
  todos: []
};

export function todoReducer(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [...state.todos, {
          text: action.payload.text,
          completed: false
        }]
      };
    case TOGGLE_TODO:
      return {
        ...state,
        todos: state.todos.map((todo, index) =>
          index === action.payload.index
            ? { ...todo, completed: !todo.completed }
            : todo
        )
      };
    default:
      return state;
  }
}

Эволюция подходов к организации кода

1. По типу сущности (feature-based)

Распространённый подход — группировка по функциональности:

src/
  features/
    todos/
      actions.js
      reducer.js
      types.js
      index.js
    user/
      actions.js
      reducer.js

2. Ducks-паттерн

Предлагает объединять связанные действия, типы и редьюсеры в одном модуле:

// todosSlice.js (Ducks-подход)
const ADD_TODO = 'todos/ADD_TODO';
const TOGGLE_TODO = 'todos/TOGGLE_TODO';

export const addTodo = (text) => ({
  type: ADD_TODO,
  payload: { text }
});

const initialState = {
  items: []
};

export default function reducer(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return { ...state, items: [...state.items, action.payload.text] };
    default:
      return state;
  }
}

3. Redux Toolkit (современный стандарт)

RTK официально рекомендует использовать "слайсы" (slices), которые объединяют action creators и reducer логику:

// todosSlice.js с использованием Redux Toolkit
import { createSlice } from '@reduxjs/toolkit';

const todosSlice = createSlice({
  name: 'todos',
  initialState: {
    items: []
  },
  reducers: {
    addTodo: (state, action) => {
      state.items.push({
        text: action.payload,
        completed: false
      });
    },
    toggleTodo: (state, action) => {
      const todo = state.items[action.payload];
      todo.completed = !todo.completed;
    }
  }
});

// Автоматически генерируются action creators:
// - todosSlice.actions.addTodo(text)
// - todosSlice.actions.toggleTodo(index)

export const { addTodo, toggleTodo } = todosSlice.actions;
export default todosSlice.reducer;

Преимущества раздельного хранения

  • Чистая архитектура: Чёткое разделение ответственности
  • Масштабируемость: Легко добавлять новые action types без изменения reducer
  • Тестируемость: Action creators и reducer можно тестировать независимо
  • Совместимость с middleware: Промежуточное ПО (как redux-thunk, redux-saga) работает с action, не затрагивая reducer

Когда можно хранить вместе?

  1. Маленькие проекты: Для простых приложений разделение может быть избыточным
  2. Использование Redux Toolkit: Слайсы инкапсулируют связанную логику
  3. Паттерн Ducks: Для самоописываемых модулей

Вывод

Хотя исторически action и reducer хранились раздельно, современная экосистема Redux, особенно с Redux Toolkit, двигается в сторону более тесной интеграции через слайсы. Выбор подхода зависит от:

  • Размера и сложности приложения
  • Командных соглашений
  • Используемых инструментов (классический Redux vs Redux Toolkit)
  • Требований к масштабируемости и поддерживаемости

Рекомендация: Для новых проектов используйте Redux Toolkit и его концепцию слайсов — это официально поддерживаемый стандарт, который уменьшает boilerplate-код и предоставляет лучший developer experience, сохраняя при этом все преимущества архитектуры Redux.

Хранятся ли вместе action и reducer в Redux | PrepBro