Учебники

Redux — Редукторы

Редукторы — это чистая функция в Redux. Чистые функции предсказуемы. Редукторы — единственный способ изменить состояния в Redux. Это единственное место, где вы можете написать логику и вычисления. Функция Reducer примет предыдущее состояние приложения и отправляемого действия, вычислит следующее состояние и вернет новый объект.

Следующие несколько вещей никогда не должны выполняться внутри редуктора:

  • Мутация аргументов функций
  • API-вызовы и логика маршрутизации
  • Вызов не чистой функции, например, Math.random ()

Ниже приведен синтаксис редуктора —

(state,action) => newState

Давайте продолжим пример показа списка товаров на веб-странице, который обсуждается в модуле создателей действий. Давайте посмотрим ниже, как написать его редуктор.

const initialState = {
   isLoading: false,
   items: []
};
const reducer = (state = initialState, action) => {
   switch (action.type) {
      case 'ITEMS_REQUEST':
         return Object.assign({}, state, {
            isLoading: action.payload.isLoading
         })
      case ITEMS_REQUEST_SUCCESS':
         return Object.assign({}, state, {
            items: state.items.concat(action.items),
            isLoading: action.isLoading
         })
      default:
         return state;
   }
}
export default reducer;

Во-первых, если вы не установили состояние в «initialState», Redux вызывает reducer с неопределенным состоянием. В этом примере кода функция JavaScript concat () используется в ‘ITEMS_REQUEST_SUCCESS’, которая не меняет существующий массив; вместо этого возвращает новый массив.

Таким образом, вы можете избежать мутации состояния. Никогда не пишите напрямую государству. В ‘ITEMS_REQUEST’ мы должны установить значение состояния из полученного действия.

Уже обсуждалось, что мы можем записать нашу логику в редуктор и разделить ее на основе логических данных. Давайте посмотрим, как мы можем разделить редукторы и объединить их вместе в качестве корневого редуктора при работе с большим приложением.

Предположим, мы хотим создать веб-страницу, где пользователь может получить доступ к статусу заказа продукта и просмотреть информацию в списке пожеланий. Мы можем разделить логику в разных файлах редукторов и заставить их работать независимо. Предположим, что действие GET_ORDER_STATUS отправлено для получения статуса заказа, соответствующего некоторому идентификатору заказа и идентификатору пользователя.

/reducer/orderStatusReducer.js
import { GET_ORDER_STATUS } from ‘../constants/appConstant’;
export default function (state = {} , action) {
   switch(action.type) {
      case GET_ORDER_STATUS:
         return { ...state, orderStatusData: action.payload.orderStatus };
      default:
         return state;
   }
}

Аналогично, предположим, что действие GET_WISHLIST_ITEMS отправляется, чтобы получить информацию о списке пожеланий пользователя, соответствующую пользователю.

/reducer/getWishlistDataReducer.js
import { GET_WISHLIST_ITEMS } from ‘../constants/appConstant’;
export default function (state = {}, action) {
   switch(action.type) {
      case GET_WISHLIST_ITEMS:
         return { ...state, wishlistData: action.payload.wishlistData };
      default:
         return state;
   }
}

Теперь мы можем объединить оба редуктора с помощью утилиты Redux combReducers. CombReducers генерирует функцию, которая возвращает объект, значения которого являются различными функциями редуктора. Вы можете импортировать все редукторы в файл редуктора индекса и объединить их вместе как объект с соответствующими именами.

/reducer/index.js
import { combineReducers } from redux’;
import OrderStatusReducer from ‘./orderStatusReducer’;
import GetWishlistDataReducer from ‘./getWishlistDataReducer’;

const rootReducer = combineReducers ({
   orderStatusReducer: OrderStatusReducer,
   getWishlistDataReducer: GetWishlistDataReducer
});
export default rootReducer;

Теперь вы можете передать этот rootReducer методу createStore следующим образом: