рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рдХрдо рдХрд░реЗрдВ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд┐рдбреНрдпреВрдХреНрд╕, рд░реЗрдбрдХреНрд╕-рд╕рд╛рдЧрд╛ рдореЗрдВ рдХреЛрдб рдХреА рдкрдардиреАрдпрддрд╛ рдХреЛ рдмрдврд╝рд╛рдПрдВ

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд┐рдбрдХреНрд╕ рдФрд░ рд░реЗрдбрдХреНрд╕-рд╕рд╛рдЧрд╛ рдмрдВрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ , рдпрд╛ рдмрд▓реНрдХрд┐, рдЬреЛ "рдмрд╛рдЗрдХ" рдореИрдВ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдФрд░ рдЗрд╕рдХреА рдзрд╛рд░рдгрд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

рдореБрдЭреЗ рдХреНрдпрд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛


рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-redux рдФрд░ redux-рдЧрд╛рдерд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ , рд╕рд░рд▓, рд▓рдЪреАрд▓рд╛, рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдб рдЕрддрд┐рд░реЗрдХ рд╣реИред рдореБрдЦреНрдп рддрддреНрд╡ рд╣реИрдВ:

  1. рдШрдЯрдирд╛ рдХрд╛рд░рдЦрд╛рдиреЛрдВ


    const actionCreatorFactory = type => payload => ({ type, payload });
    
    export const INITIALIZE = 'INITIALIZE';
    
    export const ON_FIELD_CHANGE = 'ON_FIELD_CHANGE';
    export const onFieldChange = actionCreatorFactory(ON_FIELD_CHANGE);
    
    export const HANDLE_FIELD = 'HANDLE_FIELD';
    export const handleField = actionCreatorFactory(HANDLE_FIELD);
    
    export const GO_TO_NEXT_STEP = 'GO_TO_NEXT_STEP';
    export const goToNextStep = actionCreatorFactory(GO_TO_NEXT_STEP);
    

    рдЬреИрд╕реЗ, рдХрдИ рдЪреАрдЬреЗрдВ рдореБрдЭреЗ рднреНрд░рдорд┐рдд рдХрд░рддреА рд╣реИрдВ:

    - рдШрдЯрдирд╛рдУрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдгред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд░рдВрддрд░ рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рднреА рдХрд╛рд░рдЦрд╛рдиреЗ рдореЗрдВ рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдКрдВрдЯ ( рдХреИрдорд▓рдХреЗрдЬрд╝ ) рдЕрдзрд┐рд╕реВрдЪрдирд╛ рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдирд╛рдо рдХреЗ рд╕рдорд╛рди рд╣реЛрдЧрд╛ ред

    - рдпрджрд┐ рдЖрдк рдкреЗрд▓реЛрдб рд╕рдВрд░рдЪрдирд╛ рдХреЛ рднреВрд▓ рдЧрдП рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдпрд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ reducer / рдЧрд╛рдерд╛ рдкрд░ рдЬрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ , рдЬрд╣рд╛рдВ рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рд╡рд╣рд╛рдВ рдХреНрдпрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реИред
  2. рдХрдо рдХрд░рдиреЗ рд╡рд╛рд▓реА


    import getInitialState, {
      formDataInitialState as initialState,
    } from '../helpers/initialState';
    import { HANDLE_FIELD_DONE, ON_FIELD_CHANGE, RESET } from '../actionCreators';
    
    export default (state = initialState, { type, payload }) => {
      switch (type) {
        case RESET: {
          return getInitialState().formDataInitialState;
        }
    
        case ON_FIELD_CHANGE: {
          const { name } = payload;
          return {
            ...state,
            [name]: '',
          }
        }
    
        case HANDLE_FIELD_DONE: {
          const { name, value } = payload;
          return {
            ...state,
            [name]: value,
          }
        }
      }
    
      return state;
    };
    

    рдпрд╣рд╛рдВ, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреЗрд╡рд▓ рд╕реНрд╡рд┐рдЪ рдирд┐рд░реНрдорд╛рдг рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИ
  3. рдЧрд╛рдерд╛


    import { all, put, select, fork, takeEvery } from 'redux-saga/effects';
    import { runServerSideValidation } from '../actionCreators';
    import { HANDLE_FIELD } from '../actionCreators';
    
    function* takeHandleFieldAction() {
      yield takeEvery(HANDLE_FIELD, function*({ payload }) {
        const { validation, formData } = yield select(
          ({ validation, formData }) => ({
            validation: validation[payload.name],
            formData,
          })
        );
    
        const valueFromState = formData[payload.name];
    
        if (payload.value !== valueFromState) {
          const { name, value } = payload;
          const { validator } = validation.serverValidator;
          yield put(
            runServerSideValidation({
              name,
              value,
              validator,
              formData,
            })
          );
        }
      });
    }
    
    export default function* rootSaga() {
      yield all([fork(takeHandleFieldAction())]);
    }
    

    рд╕рдЧрд╛рдУрдВ рдореЗрдВ, рд╕рдмрд╕реЗ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рд╣реИ рдкрдврд╝рдиреЗ рдореЗрдВ рдХрдард┐рдирд╛рдИред рд╕рд┐рд░реНрдл рдЧрд╛рдерд╛ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд╕рд░реА рдирд┐рдЧрд╛рд╣ред рдЗрд╕рдХрд╛ рдПрдХ рдХрд╛рд░рдг рдЧрд╣рд░рд╛ рдШреЛрдВрд╕рд▓рд╛ рд╣реИред рдЖрдк рдмреЗрд╢рдХ рдЧрд╣рд░рд╛рдИ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реНрд░рдорд┐рдХреЛрдВ рдХреЛ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЕрддрд┐рд░реЗрдХ рдмрдврд╝ рдЬрд╛рддрд╛ рд╣реИред

    import { all, put, select, fork, takeEvery } from 'redux-saga/effects';
    import { runServerSideValidation } from '../actionCreators';
    import { HANDLE_FIELD } from '../actionCreators';
    
    function* takeHandleFieldWorker({ payload }) {
        const { validation, formData } = yield select(
          ({ validation, formData }) => ({
            validation: validation[payload.name],
            formData,
          })
        );
    
        const valueFromState = formData[payload.name];
    
        if (payload.value !== valueFromState) {
          const { name, value } = payload;
          const { validator } = validation.serverValidator;
          yield put(
            runServerSideValidation({
              name,
              value,
              validator,
              formData,
            })
          );
      }
    }
    
    function* takeHandleFieldWatcher() {
      yield takeEvery(HANDLE_FIELD, takeHandleFieldWorker);
    }
    
    export default function* rootSaga() {
      yield all([fork(takeHandleFieldWatcher())]);
    }
    

    рдРрд╕реЗ рдЪреЗрдХ рднреА рд╣реИрдВ рдЬреЛ рдпрд╛ рддреЛ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдХреЛ рдмрдврд╝рд╛ рджреЗрдВрдЧреЗ, рдпрд╛ рдЧрд╛рдерд╛ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рдмрд┐рдВрджреБ рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗ, рдЬрд┐рд╕рд╕реЗ рд╣рдорд╛рд░рд╛ рдХреЛрдб рдмрд┐рдЧрдбрд╝ рдЬрд╛рддрд╛ рд╣реИред

рдореИрдВ рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ


рдХреНрд░рдо рдореЗрдВ рдЪрд▓рддреЗ рд╣реИрдВред

  1. рдШрдЯрдирд╛ рдХрд╛рд░рдЦрд╛рдиреЛрдВ


    import { actionsCreator, payload } from 'sweet-redux-saga';
    
    @actionsCreator()
    class ActionsFactory {
      initialize;
      
      @payload('field', 'value')
      onFieldChange;
      
      @payload('field')
      handleField;
      
      @payload('nextStep')
      goToNextStep;
    }
    

    actionsCreator(). , (initialize;/onFieldChange;/handleField;/gpToNextStep;) action creator. , payload(...[fieldNames]). :

    class ActionsFactory {
      initialize = () => ({
        type: 'INITIALIZE',
        payload: undefined,
      });
    
      onFieldChange = (field, value) => ({
        type: 'ON_FIELD_CHANGE',
        payload: {
          field,
          value,
        },
      });
    
      handleField = field => ({
        type: 'HANDLE_FIELD',
        payload: {
          field,
        },
      });
    
      goToNextStep = nextStep => ({
        type: 'GO_TO_NEXT_STEP',
        payload: {
          nextStep,
        },
      });
    }
    

    toString, toPrimitive, valueOf. :

    const actionsFactory = new ActionsFactory();
    console.log(String(actionsFactory.onFieldChange)); // 'ON_FIELD_CHANGE'
    

  2. import getInitialState, {
      formDataInitialState as initialState,
    } from '../helpers/initialState';
    import { HANDLE_FIELD_DONE, ON_FIELD_CHANGE, RESET } from '../actionCreators';
    import { reducer } from '../../../leadforms-gen-v2/src/decorators/ReducerDecorator';
    
    @reducer(initialState)
    export class FormDataReducer {
      [RESET]() {
        return getInitialState().formDataInitialState;
      }
    
      [ON_FIELD_CHANGE](state, payload) {
        const { name } = payload;
        return {
          ...state,
          [name]: '',
        };
      }
    
      [HANDLE_FIELD_DONE](state, payload) {
        const { name, value } = payload;
        return {
          ...state,
          [name]: value,
        };
      }
    }
    

    reducer([initialState]). , , .

    function reducer(state = initialState, action) {
      if (!action) {
        return state;
      }
    
      const reducer = instance[action.type];
      if (reducer && typeof reducer === 'function') {
        return reducer(state, action.payload);
      }
    
      return state;
    }
    

  3. import { all, put, select, } from 'redux-saga/effects';
    import { runServerSideValidation } from '../actionCreators';
    import { HANDLE_FIELD } from '../actionCreators';
    import { sagas, takeEvery, filterActions } from 'sweet-redux-saga';
    
    @sagas()
    class MySagas {
      @takeEvery([HANDLE_FIELD])
      @filterActions(
        ({state, payload }) => state.formData[payload.name] === payload.value
      )
      * takeHandleFieldAction({ payload }) {
        const { validation, formData } = yield select(({ validation, formData }) => ({
          validation: validation[payload.name],
          formData,
        }));
    
        const { name, value } = payload;
        const { validator } = validation.serverValidator;
        yield put(
          runServerSideValidation({
            name,
            value,
            validator,
            formData,
          })
        );
      }
    }
    
    export default function* rootSaga() {
      yield all([
        new MySagas(),
      ]);
    }
    

    рд╕рдЧрд╛ () рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВред рдХрдХреНрд╖рд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╕рдордп, рд╣рдореЗрдВ рдПрдХ рдлрдВрдХреНрд╢рди рдЬрдирд░реЗрдЯрд░ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬреЛ рдЯреЗрдХрдПрд╡рд░ ([... [рдПрдХреНрд╢рдирдЯрд╛рдЗрдкреНрд╕]]) рдпрд╛ рд▓реЗрд▓реИрд╕реНрдЯреЗрд╕реНрдЯ ([... [рдПрдХреНрд╢рдирдЯрд╛рдЗрдкреНрд╕]] рдПрдиреЛрдЯреЗрд╢рди рд╕реЗ рдЕрд▓рдЧ рдереНрд░реЗрдб рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ :

    function* mySagas() {
      yield all([fork(mySagas.takeHandleFieldAction())]);
    }
    

    рдлрд╝рд┐рд▓реНрдЯрд░рдПрдХреНрд╢рдВрд╕ ({рд╕реНрдЯреЗрдЯ, рдЯрд╛рдЗрдк, рдкреЗрд▓реЛрдб}) рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдЦреЗрддреЛрдВ рдХреЗ рд╕рд╛рде рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ , рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЧрд╛рдерд╛ рдХреЗрд╡рд▓ рддрднреА рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рдлрд╝рдВрдХреНрд╢рди рд╕рд╣реА рд╣реЛ ред

рдирд┐рд╖реНрдХрд░реНрд╖


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЗрди рд╕рд░рд▓ рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╕рдЧрд╛ рд╕рд╛рдл рдФрд░ рд╕реНрд╡рдЪреНрдЫ рд╣реЛ рдЧрдП, рдФрд░ рдирдП рддрд░реНрдХ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдХрдо рд╣реЛ рдЧрдИред рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЖрд╕рд╛рди рд╣реЛ рдЧрдпрд╛ рд╣реИред

рдореИрдВрдиреЗ рдореАрдареА-рд▓рд╛рд▓-рдЧрд╛рдерд╛ рдкреИрдХреЗрдЬ рдореЗрдВ рдпреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ рдХреАрдВ ред рдпрджрд┐ рдЕрдиреНрдп рдЙрдкрд╛рдп рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдореЗрд░реЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред

All Articles