Наверняка многие из вас, кто постоянно работают с React + Redux (а может не только с React), постоянно совершают множество однотипных действий. В оригинальном исполнении задача эта монотонная и включает в себя постоянное создание экшенов и редюсеров. Тем более, если приходится работать с какими-то экстраординарными кейсами, в игру включаются экшены с префиксами.
Ваш покорный слуга также испытал очень много батхерта страданий, пока работал по старинке, через switch -> case, но я взглянул на задачу немного с другой стороны и привёл к единообразию это в более удобную функционально — объектную форму записи.
И так — после некоторого времени я (master-7) и мой коллега (one-more) попробовали справиться с этим страшным сном фронтэндера и создали весьма интересную библиотечку Redux-Utils
Конечно же, мы попытались написать общепонятное и исчерпывающее ридми, но для затравки — несколько примеров в статье.
Одна из самых интересных фичей — это объектное создание редюсеров.
import {Reducer} from 'redux-util' import {UserState} from 'types/UserState' import { GET_USER_DATA_REQUEST, GET_USER_DATA_SUCCESS, GET_USER_DATA_FAIL } from 'services/actionTypes' const initialState: UserState = []; export default Reducer(initialState, { [GET_USER_DATA_REQUEST]: () => null, [GET_USER_DATA_SUCCESS]: (state, action) => ({ ...state, data: action.users }), [GET_USER_DATA_FAIL]: (state, action) => ({ ...state, error: action.error }) });
Как вы можете видеть, код стал намного более читабельным по сравнению с записью вида:
import {Reducer} from 'redux-util' import {UserState} from 'types/UserState' import { GET_USER_DATA_REQUEST, GET_USER_DATA_SUCCESS, GET_USER_DATA_FAIL } from 'services/actionTypes' const initialState: UserState = []; export default function Reducer(state = initialState, action) => { switch (action.type) { case GET_USER_DATA_REQUEST: return null; case GET_USER_DATA_REQUEST: return { ...state, data: action.users }; case GET_USER_DATA_FAIL: return { ...state, error: action.error }; default: return state; }
Ну и киллер фича номер два — посмотрим на создание экшенов:
import {buildGenericActionCreator} from 'redux-util' const START_LOADING = 'START_LOADING'; const END_LOADING = 'END_LOADING'; export const startLoadingActionCreator = buildGenericActionCreator(START_LOADING); export const endLoadingActionCreator = buildGenericActionCreator(END_LOADING); // .... import {startLoadingActionCreator, endLoadingActionCreator} from 'loading-reducer' const PREFIX = 'PREFIX'; const startLoading = startLoadingActionCreator(PREFIX); const endLoading = endLoadingActionCreator(PREFIX); export const loadUser = () => (dispatch: Dispatch) => { dispatch(startLoading()); return api.fetchUser().then( response => { dispatch( loadUserDataAction(response) ); dispatch(endLoading()); } ); };
И еще много интересного вы можете найти в ридми проекта! Надеюсь, данная библиотека сделает вашу работу легче.
ссылка на оригинал статьи https://habrahabr.ru/post/327244/
Добавить комментарий