Reducer рд╕рдВрдЧрдарди - рдПрдХ рдХрджрдо рдЖрдЧреЗ рд▓реЗ рдЬрд╛рдирд╛


рд╣рдо рдпрд╣рд╛рдБ рдХреНрдпрд╛ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ?


рд╣рдо рдЕрдкрдиреЗ Redux / NGRX рдРрдк рдореЗрдВ рд░рд┐рдбреНрдпреВрд╕рд░реНрд╕ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХрд╛ рдЕрд╡рд▓реЛрдХрди рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдкрд┐рдЫрд▓реЗ рджреЛ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ рд╣реБрдЖ рдерд╛ред рд╡реЗрдирд┐рд▓рд╛ switch-case рд╕реЗ рд╢реБрд░реВ, рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдПрдХ reducer рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдЕрдВрдд рдореЗрдВ рд╡рд░реНрдЧ-рдЖрдзрд╛рд░рд┐рдд reducers рдХреЗ рд╕рд╛рде рдмрд╕рдирд╛ред рд╣рдо рдХреЗрд╡рд▓ рдХреИрд╕реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдирд╣реАрдВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рдХреНрдпреЛрдВред


рдпрджрд┐ рдЖрдк Redux / NGRX рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕ рд▓реЗрдЦ рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдпрджрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░ рддрдХрдиреАрдХ рд╕реЗ рд░рд┐рдбреНрдпреВрд╕рд░ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рддреЛ рдХреНрд▓рд╛рд╕-рдЖрдзрд╛рд░рд┐рдд рд░реАрдбреНрдпреВрд╕рд░ рдкрд░ рд╕рд╣реА рдХреВрджрдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рд╡реЗрдирд┐рд▓рд╛ рд╕реНрд╡рд┐рдЪ-рдХреЗрд╕


рддреЛ рдЖрдЗрдП, рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдПрдХ рдЗрдХрд╛рдИ рдмрдирд╛рдиреЗ рдХреЗ рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдХрд╛рдо рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рдЗрд╕ рдмрд╛рд░ рдореЗрд░рд╛ рд╕реБрдЭрд╛рд╡ рд╣реИ рдХрд┐ рд╣рдо рдпрд╣ рд╡рд░реНрдгрди рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдПрдХ рдирдИ рдЬреЗрдбреА рдХреИрд╕реЗ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред


 const actionTypeJediCreateInit = 'jedi-app/jedi-create-init' const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success' const actionTypeJediCreateError = 'jedi-app/jedi-create-error' const reducerJediInitialState = { loading: false, // List of our jedi data: [], error: undefined, } const reducerJedi = (state = reducerJediInitialState, action) => { switch (action.type) { case actionTypeJediCreateInit: return { ...state, loading: true, } case actionTypeJediCreateSuccess: return { loading: false, data: [...state.data, action.payload], error: undefined, } case actionTypeJediCreateError: return { ...state, loading: false, error: action.payload, } default: return state } } 

рдореБрдЭреЗ рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдиреЗ рджреЗрдВ, рдореИрдВрдиреЗ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд░рд┐рдбреНрдпреВрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрднреА рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдореЗрд░рд╛ рддрд░реНрдХ рддреАрди рдЧреБрдирд╛ рд╣реИ:


  • switch-case рддрдирд╛рд╡ рдХреЗ рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рдкрд░рд┐рдЪрдп рджреЗрддрд╛ рд╣реИ, рдЯрдкрдХрд╛ рд╣реБрдЖ рдкрд╛рдЗрдк, рдЬрд┐рд╕реЗ рд╣рдо рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ рд╕рдордп рдореЗрдВ рдкреИрдЪ рдХрд░рдирд╛ рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рд╣рдореЗрд╢рд╛ break рдореЗрдВ рд░рдЦрдирд╛ рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рддрддреНрдХрд╛рд▓ return рдирд╣реАрдВ рдХрд░рддреЗ return , рд╣рдо рд╣рдореЗрд╢рд╛ default рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рд╣рд░ рд░рд┐рдбреНрдпреВрд╕рд░ рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред
  • switch-case рдореЗрдВ рд╕реНрд╡рдпрдВ рдХреБрдЫ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЛрдб рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рд╕рдВрджрд░реНрдн рдХреЛ рдирд╣реАрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
  • switch-case O (n), рддрд░рд╣ рдХрд╛ рд╣реИ ред рдпрд╣ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдПрдХ рдареЛрд╕ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ Redux рд╡реИрд╕реЗ рднреА рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдкреНрд░рджрд░реНрд╢рди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдореЗрд░реЗ рдЖрдВрддрд░рд┐рдХ рдкреВрд░реНрдгрддрд╛рд╡рд╛рджреА рдХреЛ рдкрд╛рдЧрд▓ рдмрдирд╛ рджреЗрддрд╛ рд╣реИред

Redux рдХрд╛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рдЬреЛ рддрд╛рд░реНрдХрд┐рдХ рдЕрдЧрд▓рд╛ рдХрджрдо рд╣реИ, рд╡рд╣ рдпрд╣ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рд░рд┐рдбреНрдпреВрд╕рд░ рдЪреБрдирдирд╛ рд╣реИред


рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рд░рд┐рдбреНрдпреВрд╕рд░ рдХрд╛ рдЪрдпрди рдХрд░рдирд╛


рд╡рд┐рдЪрд╛рд░ рд╕рд░рд▓ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд░рд╛рдЬреНрдп рдкрд░рд┐рд╡рд░реНрддрди рд░рд╛рдЬреНрдп рдФрд░ рдХреНрд░рд┐рдпрд╛ рд╕реЗ рдПрдХ рдХрд╛рд░реНрдп рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЕрдиреБрд░реВрдк рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИред рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдХреБрдВрдЬреА рдПрдХ рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рди рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рд░рд╛рдЬреНрдп (рдПрдХ reducer) рдХреЛ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рддрдм рд╣рдо рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рдЙрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдПрдХ рдЖрд╡рд╢реНрдпрдХ reducer рдЪреБрди рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ O (1) рд╣реИ, рдЬрдм рд╣рдо рдПрдХ рдирдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред


 const actionTypeJediCreateInit = 'jedi-app/jedi-create-init' const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success' const actionTypeJediCreateError = 'jedi-app/jedi-create-error' const reducerJediInitialState = { loading: false, data: [], error: undefined, } const reducerJediMap = { [actionTypeJediCreateInit]: (state) => ({ ...state, loading: true, }), [actionTypeJediCreateSuccess]: (state, action) => ({ loading: false, data: [...state.data, action.payload], error: undefined, }), [actionTypeJediCreateError]: (state, action) => ({ ...state, loading: false, error: action.payload, }), } const reducerJedi = (state = reducerJediInitialState, action) => { // Pick a reducer by action type const reducer = reducerJediMap[action.type] if (!reducer) { // Return state unchanged if we did not find a suitable reducer return state } // Run suitable reducer if found one return reducer(state, action) } 

рдпрд╣рд╛рдБ рдардВрдбреА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ reducerJedi рдЕрдВрджрд░ рддрд░реНрдХ рдХрд┐рд╕реА рднреА reducer рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдЫреЛрдЯрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рднреА рд╣реИ, рдЬрд┐рд╕реЗ рд░рд┐рдбреНрдпреВрдХреНрд╕-рдХреНрд░рд┐рдПрдЯ-рд░реЗрдбреНрдпреВрд╕рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 import { createReducer } from 'redux-create-reducer' const actionTypeJediCreateInit = 'jedi-app/jedi-create-init' const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success' const actionTypeJediCreateError = 'jedi-app/jedi-create-error' const reducerJediInitialState = { loading: false, data: [], error: undefined, } const reducerJedi = createReducer(reducerJediInitialState, { [actionTypeJediCreateInit]: (state) => ({ ...state, loading: true, }), [actionTypeJediCreateSuccess]: (state, action) => ({ loading: false, data: [...state.data, action.payload], error: undefined, }), [actionTypeJediCreateError]: (state, action) => ({ ...state, loading: false, error: action.payload, }), }) 

рдЕрдЪреНрдЫрд╛ рдФрд░ рд╕реБрдВрджрд░, рд╣реБрд╣? рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕ рд╕реБрдВрджрд░ рдЕрднреА рднреА рдХреБрдЫ рдЪреЗрддрд╛рд╡рдиреА рд╣реИ:


  • рдЬрдЯрд┐рд▓ рд░рд┐рдбреНрдпреВрд╕рд░реНрд╕ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдореЗрдВ рдпрд╣ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реА рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдЫреЛрдбрд╝рдиреА рдкрдбрд╝рддреА рд╣реИрдВ рдХрд┐ рдпрд╣ рд░рд┐рдбреНрдпреВрд╕рд░ рдХреНрдпрд╛ рдФрд░ рдХреНрдпреЛрдВ рдХрд░рддрд╛ рд╣реИред
  • рд╡рд┐рд╢рд╛рд▓ reducer рдХреЗ рдирдХреНрд╢реЗ рдХреЛ рдкрдврд╝рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред
  • рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдбреНрдпреВрд╕рд░ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдПрдХреНрд╢рди рдЯрд╛рдЗрдк рд╣реЛрддрд╛ рд╣реИред рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдореИрдВ рдПрдХ рд╣реА reducer рдХреЛ рдХрдИ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЪрд▓рд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ?

рд░рд╛рдд рдХреЗ рд░рд╛рдЬреНрдп рдореЗрдВ рдХреНрд▓рд╛рд╕-рдЖрдзрд╛рд░рд┐рдд рд░реЗрдбреНрдпреВрд╕рд░ рдореЗрд░реЗ рдкреНрд░рдХрд╛рд╢ рдХрд╛ рд╢реЗрдб рдмрди рдЧрдпрд╛ред


рд╡рд░реНрдЧ-рдЖрдзрд╛рд░рд┐рдд рд░реЗрдбреНрдпреВрд╕рд░


рдЗрд╕ рдмрд╛рд░ рдореБрдЭреЗ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдВ:


  • рдХреНрд▓рд╛рд╕ рдХреЗ рддрд░реАрдХреЗ рд╣рдорд╛рд░реЗ рд░рд┐рдбреНрдпреВрд╕рд░ рд╣реЛрдВрдЧреЗ рдФрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдореЗрдВ рдирд╛рдо рд╣реИрдВ, рдЬреЛ рдПрдХ рдЙрдкрдпреЛрдЧреА рдореЗрдЯрд╛-рд╕реВрдЪрдирд╛ рд╣реИ, рдФрд░ рд╣рдо 90% рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
  • рдХрдХреНрд╖рд╛ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рд╕рдЬрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдХреНрд░рд┐рдпрд╛рдУрдВ рдФрд░ рд░реЗрдбреНрдпреВрд╕рд░ рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╕рд╛рди-рд╕реЗ-рдШреЛрд╖рд┐рдд рдШреЛрд╖рдгрд╛рддреНрдордХ рддрд░реАрдХрд╛ рд╣реИред
  • рд╣рдо рдЕрднреА рднреА рд╣реЗ (1) рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рд▓рд┐рдП рд╣реБрдб рдХреЗ рддрд╣рдд рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрджрд┐ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдЪрд┐рдд рд╕реВрдЪреА рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ, рддреЛ рдЪрд▓реЛ рдЦреБрджрд╛рдИ рдХрд░рддреЗ рд╣реИрдВ!


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдпрд╣ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рд╣рдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


 const actionTypeJediCreateInit = 'jedi-app/jedi-create-init' const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success' const actionTypeJediCreateError = 'jedi-app/jedi-create-error' class ReducerJedi { // Take a look at "Class field delcaratrions" proposal, which is now at Stage 3. // https://github.com/tc39/proposal-class-fields initialState = { loading: false, data: [], error: undefined, } @Action(actionTypeJediCreateInit) startLoading(state) { return { ...state, loading: true, } } @Action(actionTypeJediCreateSuccess) addNewJedi(state, action) { return { loading: false, data: [...state.data, action.payload], error: undefined, } } @Action(actionTypeJediCreateError) error(state, action) { return { ...state, loading: false, error: action.payload, } } } 

рдЕрдм рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЬрд╣рд╛рдВ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдХрджрдо рд╕реЗ рдХрджрдо рдорд┐рд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдЪрд░рдг 1. рдПрдХреНрд╢рди рдбреЗрдХреЛрд░реЗрдЯрд░ред


рд╣рдо рдпрд╣рд╛рдВ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдмрд╛рдж рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдореЗрдЯрд╛-рд╕реВрдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рд░рд┐рдлреНрд▓реЗрдХреНрдЯ -рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдкреЙрд▓реАрдлрд┐рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ , рдЬреЛ рд░рд┐рдлреНрд▓реЗрдХреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдореЗрдЯрд╛-рдбреЗрдЯрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓рд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж рдпрд╣ рдбреЗрдХреЛрд░реЗрдЯрд░ рдореЗрдЯрд╛-рдбреЗрдЯрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдкрдиреЗ рддрд░реНрдХ (рдПрдХреНрд╢рди рдЯрд╛рдЗрдк) рдХреЛ рдПрдХ рд╡рд┐рдзрд┐ рд╕реЗ рдЬреЛрдбрд╝ рджреЗрдЧрд╛ред


 const METADATA_KEY_ACTION = 'reducer-class-action-metadata' export const Action = (...actionTypes) => (target, propertyKey, descriptor) => { Reflect.defineMetadata(METADATA_KEY_ACTION, actionTypes, target, propertyKey) } 

рдЪрд░рдг 2. рдПрдХ reducer рд╡рд░реНрдЧ рд╕реЗ рдПрдХ reducer рд╕рдорд╛рд░реЛрд╣ рдмрдирд╛рдирд╛


рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ reducer рдПрдХ рд╢реБрджреНрдз рдХрд╛рд░реНрдп рд╣реИ рдЬреЛ рдПрдХ рд░рд╛рдЬреНрдп рдФрд░ рдПрдХ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдирдпрд╛ рд░рд╛рдЬреНрдп рджреЗрддрд╛ рд╣реИред рд╡реИрд╕реЗ, рдХреНрд▓рд╛рд╕ рдПрдХ рдлрдВрдХреНрд╢рди рд╣реИ, рд▓реЗрдХрд┐рди рдИрдПрд╕ 6 рдХреНрд▓рд╛рд╕реЗрд╕ рдХреЛ new рдмрд┐рдирд╛ рдЗрдирд╡рд╛рдЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░реАрдХреЗ рд╕реЗ рдХреНрд▓рд╛рд╕ рд╕реЗ рдмрд╛рд╣рд░ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд░реЗрдбреНрдпреВрд╕рд░ рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдЗрд╕реЗ рдмрджрд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред


рд╣рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ рдХреЛ рд▓реЗ рдЬрд╛рдПрдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐, рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдПрдХрддреНрд░ рдХрд░реЗрдЧреА, рдПрдХ reducer рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдЧреА рдФрд░ рдЙрд╕ reducer рдХреЗ рдирдХреНрд╢реЗ рд╕реЗ рдЕрдВрддрд┐рдо рд░реЗрдбреНрдпреВрд╕рд░ рдмрдирд╛рдПрдЧреАред


рдпрд╣рд╛рдБ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрдХреНрд╖рд╛ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрд░реАрдХреЗ рдХреА рдЬрд╛рдБрдЪ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


 const getReducerClassMethodsWthActionTypes = (instance) => { // Get method names from class' prototype const proto = Object.getPrototypeOf(instance) const methodNames = Object.getOwnPropertyNames(proto).filter( (name) => name !== 'constructor', ) // We want to get back a collection with action types and corresponding reducers const res = [] methodNames.forEach((methodName) => { const actionTypes = Reflect.getMetadata( METADATA_KEY_ACTION, instance, methodName, ) // We want to bind each method to class' instance not to lose `this` context const method = instance[methodName].bind(instance) // We might have many action types associated with a reducer actionTypes.forEach((actionType) => res.push({ actionType, method, }), ) }) return res } 

рдЕрдм рд╣рдо рдкреНрд░рд╛рдкреНрдд рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдПрдХ рд░рд┐рдбреНрдпреВрд╕рд░ рдорд╛рдирдЪрд┐рддреНрд░ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


 const getReducerMap = (methodsWithActionTypes) => methodsWithActionTypes.reduce((reducerMap, { method, actionType }) => { reducerMap[actionType] = method return reducerMap }, {}) 

рддреЛ рдЕрдВрддрд┐рдо рд╕рдорд╛рд░реЛрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИред


 import { createReducer } from 'redux-create-reducer' const createClassReducer = (ReducerClass) => { const reducerClass = new ReducerClass() const methodsWithActionTypes = getReducerClassMethodsWthActionTypes( reducerClass, ) const reducerMap = getReducerMap(methodsWithActionTypes) const initialState = reducerClass.initialState const reducer = createReducer(initialState, reducerMap) return reducer } 

рдФрд░ рд╣рдо рдЗрд╕реЗ рдЕрдкрдиреЗ ReducerJedi рд╡рд░реНрдЧ рдкрд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


 const reducerJedi = createClassReducer(ReducerJedi) 

рдЪрд░рдг 3. рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд╡рд┐рд▓рдпред


 // We move that generic code to a dedicated module import { Action, createClassReducer } from 'utils/reducer-class' const actionTypeJediCreateInit = 'jedi-app/jedi-create-init' const actionTypeJediCreateSuccess = 'jedi-app/jedi-create-success' const actionTypeJediCreateError = 'jedi-app/jedi-create-error' class ReducerJedi { // Take a look at "Class field delcaratrions" proposal, which is now at Stage 3. // https://github.com/tc39/proposal-class-fields initialState = { loading: false, data: [], error: undefined, } @Action(actionTypeJediCreateInit) startLoading(state) { return { ...state, loading: true, } } @Action(actionTypeJediCreateSuccess) addNewJedi(state, action) { return { loading: false, data: [...state.data, action.payload], error: undefined, } } @Action(actionTypeJediCreateError) error(state, action) { return { ...state, loading: false, error: action.payload, } } } export const reducerJedi = createClassReducer(ReducerJedi) 

рдЕрдЧрд▓реЗ рдЪрд░рдг


рдпрд╣рд╛рдБ рд╣рдо рдХреНрдпрд╛ рдпрд╛рдж рдХрд┐рдпрд╛:


  • рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдПрдХ рд╣реА рдХреНрд░рд┐рдпрд╛ рдХрдИ рд╡рд┐рдзрд┐рдпреЛрдВ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ? рд╡рд░реНрддрдорд╛рди рддрд░реНрдХ рдЗрд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рдирд╣реАрдВ рд╣реИред
  • рд╣рдо рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ?
  • рдпрджрд┐ рдореИрдВ рдХрдХреНрд╖рд╛-рдЖрдзрд╛рд░рд┐рдд рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдореИрдВ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░ рдирд╣реАрдВ, рдПрдХреНрд╢рди рдЯрд╛рдЗрдк рдХреИрд╕реЗ рдкрд╛рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ?

рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдирдореВрдиреЗ рдФрд░ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕рдм reducer-рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдореБрдЭреЗ рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд░реАрдбреНрдпреВрд╕рд░ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдПрдХ рдореВрд▓ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рд╣реИред @amcdnl рдХрд╛рдлреА рд╕рдордп рдкрд╣рд▓реЗ рднрдпрд╛рдирдХ ngrx- рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдЕрдм NGXS рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реИ , рдпрд╣ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдХрд┐ рдореИрдВ рдХреЛрдгреАрдп-рд╡рд┐рд╢рд┐рд╖реНрдЯ рддрд░реНрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдЦреНрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдФрд░ рдбрд┐рдХреЙрдкреНрд▓рд┐рдВрдЧ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдпрд╣рд╛рдБ reducer-class рдФрд░ ngrx-actions рдХреЗ рдмреАрдЪ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред


рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд░реАрдбреНрдпреВрд╕рд░ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдкрд╕рдВрдж рд╣реИ, рддреЛ рдЖрдк рдЕрдкрдиреЗ рдПрдХреНрд╢рди рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдлреНрд▓рдХреНрд╕-рдПрдХреНрд╢рди-рдХреНрд▓рд╛рд╕ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рдЙрдореНрдореАрдж рд╣реИ, рдЖрдкрдиреЗ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдкрд╛рдпрд╛ред рдЕрдкрдиреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореБрдЭрд╕реЗ рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ! рдореИрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рд╕рд╡рд╛рд▓реЛрдВ рдХреА рд╕рд░рд╛рд╣рдирд╛ рдХрд░рддрд╛ рд╣реВрдВред

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


All Articles