Redux-symbiote - рд▓реЗрдЦрди рдХреНрд░рд┐рдпрд╛рдПрдВ рдФрд░ рд▓рдЧрднрдЧ рдХреЛрдИ рджрд░реНрдж рдирд╣реАрдВ рдХреЗ рд╕рд╛рде reducers

рд░рд┐рдПрдХреНрдЯ-рд░рд┐рдбрдХреНрд╕ рдПрдХ рдмреЗрд╣рддрд░реАрди рдЪреАрдЬ рд╣реИред рдЬрдм рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреБрд╢рд▓ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдкрдврд╝рдирд╛ рдЖрд╕рд╛рди рд╣реЛрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рднреА рдирд┐рд░реНрдгрдп рдХреЗ рд░реВрдк рдореЗрдВ, рдХреБрдЫ рдЦрд╝рд╛рд╕рд┐рдпрддреЗрдВ рд╣реИрдВред

рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рд░рд┐рдбреНрдпреВрд╕рд░ рдХрд╛ рд╡рд┐рд╡рд░рдг рдРрд╕реА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдХреЛрдб рдореЗрдВ рдЗрди рджреЛ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХрд╛ рдХреНрд▓рд╛рд╕рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рдЕрдзрд┐рдХ рд╕рдордп рд▓реЗрдиреЗ рд╡рд╛рд▓рд╛ рдХрд╛рд░реНрдп рд╣реИред

рдХреНрд▓рд╛рд╕рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рджрд░реНрдж


рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг:

// actionTypes.js //    export const POPUP_OPEN_START = 'POPUP_OPEN_START '; export const POPUP_OPEN_PENDING = 'POPUP_OPEN_PENDING '; export const POPUP_OPEN_SUCCESS = 'POPUP_OPEN_SUCCESS '; export const POPUP_OPEN_FAIL = 'POPUP_OPEN_FAIL'; export const POPUP_CLOSE_START = 'POPUP_CLOSE_START '; export const POPUP_CLOSE_PENDING = 'POPUP_CLOSE_PENDING '; export const POPUP_CLOSE_SUCCESS = 'POPUP_CLOSE_SUCCESS '; export const POPUP_CLOSE_FAIL = 'POPUP_CLOSE_FAIL'; 

 // actions.js //    import { POPUP_OPEN_START, POPUP_OPEN_PENDING, POPUP_OPEN_SUCCESS, POPUP_OPEN_FAIL, POPUP_CLOSE_START, POPUP_CLOSE_PENDING, POPUP_CLOSE_SUCCESS, POPUP_CLOSE_FAIL } from './actionTypes'; export function popupOpenStart(name) { return { type: POPUP_OPEN_START, payload: { name }, } } export function popupOpenPending(name) { return { type: POPUP_OPEN_PENDING, payload: { name }, } } export function popupOpenFail(error) { return { type: POPUP_OPEN_FAIL, payload: { error, }, } } export function popupOpenSuccess(name, data) { return { type: POPUP_OPEN_SUCCESS, payload: { name, data }, } } export function popupCloseStart(name) { return { type: POPUP_CLOSE_START, payload: { name }, } } export function popupClosePending(name) { return { type: POPUP_CLOSE_PENDING, payload: { name }, } } export function popupCloseFail(error) { return { type: POPUP_CLOSE_FAIL, payload: { error, }, } } export function popupCloseSuccess(name) { return { type: POPUP_CLOSE_SUCCESS, payload: { name }, } } 

 // reducers.js //   import { POPUP_OPEN_START, POPUP_OPEN_PENDING, POPUP_OPEN_SUCCESS, POPUP_OPEN_FAIL, POPUP_CLOSE_START, POPUP_CLOSE_PENDING, POPUP_CLOSE_SUCCESS, POPUP_CLOSE_FAIL } from './actionTypes'; const initialState = { opened: [] }; export function popupReducer(state = initialState, action) { switch (action.type) { case POPUP_OPEN_START: case POPUP_OPEN_PENDING: case POPUP_CLOSE_START: case POPUP_CLOSE_PENDING: return { ...state, error: null, loading: true }; case POPUP_OPEN_SUCCESS : return { ...state, loading: false, opened: [ ...(state.opened || []).filter(x => x.name !== action.payload.name), { ...action.payload } ] }; case POPUP_OPEN_FAIL: return { ...state, loading: false, error: action.payload.error }; case POPUP_CLOSE_SUCCESS: return { ...state, loading: false, opened: [ ...state.opened.filter(x => x.name !== name) ] }; case POPUP_CLOSE_FAIL: return { ...state, loading: false, error: action.payload.error }; } return state; } 

рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ 3 рдлрд╛рдЗрд▓реЗрдВ рд╣реИрдВ рдФрд░ рдХрдо рд╕реЗ рдХрдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ:

  • "рдмреНрд▓реЛрдЯ" рдХреЛрдб рдХреЛ рдХреЗрд╡рд▓ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдПрдХ рдирдИ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдЬреЛрдбрд╝рдХрд░
  • рдХрд╛рд░реНрд░рд╡рд╛рдИ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдЖрдпрд╛рдд
  • рдХрд╛рд░реНрд░рд╡рд╛рдИ рд▓рдЧрд╛рддрд╛рд░ рдирд╛рдо (рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ) рдкрдврд╝рдирд╛

рдЕрдиреБрдХреВрд▓рди


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ redux-actions рдХреЗ рд╕рд╛рде рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

 import { createActions, handleActions, combineActions } from 'redux-actions' export const actions = createActions({ popups: { open: { start: () => ({ loading: true }), pending: () => ({ loading: true }), fail: (error) => ({ loading: false, error }), success: (name, data) => ({ loading: false, name, data }), }, close: { start: () => ({ loading: true }), pending: () => ({ loading: true }), fail: (error) => ({ loading: false, error }), success: (name) => ({ loading: false, name }), }, }, }).popups const initialState = { opened: [] }; export const accountsReducer = handleActions({ [ combineActions( actions.open.start, actions.open.pending, actions.open.success, actions.open.fail, actions.close.start, actions.close.pending, actions.close.success, actions.close.fail ) ]: (state, { payload: { loading } }) => ({ ...state, loading }), [combineActions(actions.open.fail, actions.close.fail)]: (state, { payload: { error } }) => ({ ...state, error }), [actions.open.success]: (state, { payload: { name, data } }) => ({ ...state, error: null, opened: [ ...(state.opened || []).filter(x => x.name !== name), { name, data } ] }), [actions.close.success]: (state, { payload: { name } }) => ({ ...state, error: null, opened: [ ...state.opened.filter(x => x.name !== name) ] }) }, initialState) 

рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реНрдгрддрд╛ рдХреА рдХреЛрдИ рд╕реАрдорд╛ рдирд╣реАрдВ рд╣реИред

рджрд░реНрдж рдХрд╛ рдЗрд▓рд╛рдЬ рдХрд░реЗрдВ


рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдореЗрдВ, рдореИрдВ LestaD habr.com/en/post/350850/#comment_10706454 рджреНрд╡рд╛рд░рд╛ рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рдкрд╛рд░ рдЖрдпрд╛ рдФрд░ Redux -symbiote рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
рдЗрд╕рдиреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдФрд░ рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред

рдКрдкрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдиреЗ рд▓рдЧрд╛:

 // symbiotes/popups.js import { createSymbiote } from 'redux-symbiote'; export const initState = { opened: [] }; export const { actions, reducer } = createSymbiote(initialState, { popups: { open: { start: state => ({ ...state, error: null }), pending: state => ({ ...state }), success: (state, { name, data } = {}) => ({ ...state, opened: [ ...(state.opened || []).filter(x => x.name !== name), { name, data }) ] }), fail: (state, { error } = {}) => ({ ...state, error }) }, close: { start: state => ({ ...state, error: null }), pending: state => ({ ...state }), success: (state, { name } = {}) => ({ ...state, opened: [ ...state.opened.filter(x => x.name !== name) ] }), fail: (state, { error } = {}) => ({ ...state, error }) } } }); 

 //   import { actions } from './symbiotes/popups'; // ... export default connect( mapStateToProps, dispatch => ({ onClick: () => { dispatch(actions.open.start({ name: PopupNames.Info })); } }) )(FooComponent); 

рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдореМрдЬреВрдж рдкреЗрд╢реЗрд╡рд░реЛрдВ рд╕реЗ:

  • рд╕рднреА рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ
  • рдХрдо рдХреЛрдб
  • рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рд╕рдВрд░рдЪрд┐рдд рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡

Minuses рдХреА:

  • рдЖрдИрдбреАрдИ рд╣рдореЗрд╢рд╛ рд╕рдВрдХреЗрдд рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ
  • рдХреЛрдб рдореЗрдВ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореБрд╢реНрдХрд┐рд▓ рд╣реИ
  • рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рдирд╛рдо рдмрджрд▓рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ

рд╡рд┐рдкрдХреНрд╖ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдпрд╣ рдореЙрдбреНрдпреВрд▓ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрдЪреНрдЫреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП LestaD рдХреЛ рдзрдиреНрдпрд╡рд╛рджред

Source: https://habr.com/ru/post/hi442346/


All Articles