рд░рд┐рдПрдХреНрдЯ рдкрд░ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд░реВрдк

рдирдорд╕реНрддреЗ!

рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмреАрд╕реАрдПрд╕ рдореЗрдВ рдПрдХ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдкреИрдирд▓ рдФрд░ рдХрдИ рд░реВрдк рд╣реИрдВ, рд▓реЗрдХрд┐рди рд░рд┐рдПрдХреНрдЯ рд╕рдореБрджрд╛рдп рдореЗрдВ рдЖрдо рддреМрд░ рдкрд░ рд╕реНрд╡реАрдХреГрдд рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ - рдЙрдиреНрд╣реЗрдВ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдлреЗрд╕рдмреБрдХ рдЧрд╛рдЗрдб рдХреЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдлреЙрд░реНрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИ, рдЬрд╣рд╛рдВ рд╕рддреНрдпрд╛рдкрди рдФрд░ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ Redux-form, formik, final-form рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдпрд╛ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди рднреА рд▓рд┐рдЦрддрд╛ рд╣реИред


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рд░рд┐рдПрдХреНрдЯ рдкрд░ рд░реВрдкреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рджрд┐рдЦрд╛рдПрдВрдЧреЗред рд╣рдорд╛рд░рд╛ рд╕реНрдЯреИрдХ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛: рд░рд┐рдПрдХреНрдЯ + рдлреЙрд░реНрдорд┐рдХ + рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯред рд╣рдо рджрд┐рдЦрд╛рдПрдВрдЧреЗ:

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

рдирдП рд╡реНрдпрд╡рд╕рд╛рдп рдХрд╛рд░реНрдп рдХреЗ рд╕рд╛рде, рд╣рдордиреЗ рд╕реАрдЦрд╛ рдХрд┐ рд╣рдореЗрдВ 15-20 рд╕рдорд╛рди рд░реВрдк рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдФрд░ рдХрд╛рд▓реНрдкрдирд┐рдХ рд░реВрдк рд╕реЗ рдЙрдирдореЗрдВ рд╕реЗ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкрд░ рдПрдХ рдбрд╛рдпрдирд╛рд╕реЛрд░ рдлреЙрд░реНрдо рдерд╛, рдЬреЛ `рд╕реНрдЯреЛрд░` рдХреЗ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рдерд╛,` sagas` рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рддрд╛ рдерд╛ред рд╡рд╣ рдЕрджреНрднреБрдд рдерд╛, рд╡реНрдпрд╛рдкрд╛рд░ рдореВрд▓реНрдп рдХрд░ рд░рд╣рд╛ рдерд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧреИрд░-рд╡рд┐рд╕реНрддрд╛рд░ рдпреЛрдЧреНрдп рдФрд░ рдЧреИрд░-рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рдерд╛, рдХреЗрд╡рд▓ рдЦрд░рд╛рдм рдХреЛрдб рдФрд░ рдмреИрд╕рд╛рдЦреА рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрддред

рдХрд╛рд░реНрдп рдпрд╣ рд╣реИ: рдлреЙрд░реНрдо рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рддрд╛рдХрд┐ рдЗрд╕реЗ рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЦреИрд░, рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЛ рдпрд╛рдж рд░рдЦреЗрдВ, рдЗрд╕рдореЗрдВ рд╢реБрджреНрдз рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреЛ рдмрд╛рд╣рд░реА рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ 'redux', рдХреЗрд╡рд▓ рд╡реЗ рд╣реА рддрд░реНрдХ (рдкреНрд░реЙрдкреНрд╕) рдореЗрдВ рднреЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВред

рдФрд░ рд╡рд╣реА рд╣реБрдЖред

рд╣рдорд╛рд░реЗ рдШрдЯрдХ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдПрдХ рдЖрд╡рд░рдг (рдХрдВрдЯреЗрдирд░) рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕рдореЗрдВ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рддрд░реНрдХ (Redux рд╕реНрдЯреЛрд░ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рдХреНрд░рд┐рдпрд╛рдПрдВ рднреЗрдЬрдирд╛) рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рдХреЛ рдХреЙрд▓рдмреИрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдлрд╛рд░реНрдо рдХреА рдкреВрд░реА рд╕реВрдЪреА рд╕рд╣рд╛рд░рд╛:

interface IFormProps { //          IsSubmitting?: boolean; //     submitText?: string; //    resetText?: string; //       (  ) validateOnChange?: boolean; //     blur'e  (  ) validateOnBlur?: boolean; // ,      . config: IFieldsFormMetaModel[]; //  . fields: FormFields; //    validationSchema: Yup.MidexSchema; //     onSubmit?: () => void; //     reset  onReset?: (e: React.MouseEvent<HTMLElement>) => void; //    onChangeField?: ( e: React.SyntaticEvent<HTMLInputElement, name: string; value: string ) => void; //      +    onChangeFields?: (values: FormFields, prop: { isValid }) => void; } 

рдлреЙрд░реНрдорд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рд╣рдо <Formik /> рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

 render() { const { fields, validationSchema, validateOnBlur = true, validateOnChange = true, } = this.props; return ( <Formik initialValues={fields} render={this.renderForm} onSubmit={this.handleSubmitForm} validationSchema={validationSchema} validateOnBlur={validateOnBlur} validateOnChange={validateOnChange} validate={this.validateFormLevel} /> ); } 

`рдорд╛рдиреНрдп` рдлреЙрд░реНрдо рдХреЗ рдкреНрд░реЛрдк рдореЗрдВ, рд╣рдо` this.validateFormLevel` рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдХрдВрдЯреЗрдирд░ рдШрдЯрдХ рдХреЛ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдлрд╝реАрд▓реНрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдореМрдХрд╛ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╡реЗ рд╡реИрдз рд╣реИрдВред

 private validateFormLevel = (values: FormFields) => { const { onChangeFields, validationSchema } = this.props; if (onChangeFields) { validationSchema .validate(values) .then(() => { onChangeFields(values, { isValid: true }); }) .catch(() => { onChangeFields(values, { isValid: false }); }); } } 

рдпрд╣рд╛рдВ рд╣рдореЗрдВ рдХрдВрдЯреЗрдирд░ рдХреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рд╕рддреНрдпрд╛рдкрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдЦреЗрдд рд╡реИрдз рд╣реИрдВред рдлреЙрд░реНрдо рдЬрдорд╛ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдмрд╕ рдкреНрд░реЛрдк рдХреЛ 'onSubmit` рдХрд╣рддреЗ рд╣реИрдВ:

 private handleSubmitForm = (): void => { const { onSubmit } = this.props; if (onSubmit) { onSubmit(); } } 

рд╕рд╣рд╛рд░рд╛ рдХреЗ рд╕рд╛рде 1-5 рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪрд▓рд┐рдП 'config', 'рдлрд╝реАрд▓реНрдбреНрд╕' рдФрд░ 'validSchema' рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред

рд╕рд╣рд╛рд░рд╛ 'рд╡рд┐рдиреНрдпрд╛рд╕'


 interface IFieldsFormMetaModel { /**   */ sectionName?: string; sectionDescription?: string; fieldsForm?: Array<{ /**    */ name?: string; //          prop 'fields' /**    checked */ checked?: boolean; /** enum,      */ type?: ElementTypes; /**    */ label?: string; /**    */ helperText?: string; /**      */ required?: boolean; /**      */ disabled?: boolean; /**  -    */ minLength?: number; /**            */ initialValue?: IInitialValue; /**      */ selectItems?: ISelectItems[]; //   select, dropdown   }>; } 

рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдПрдХ рд╕рд░рдгреА рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ "рдЕрдиреБрднрд╛рдЧ" -> "рдЕрдиреБрднрд╛рдЧ рдлрд╝реАрд▓реНрдб" рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдмрд╛рд░ рдореЗрдВ рдПрдХ рдЦрдВрдб рдФрд░ рдПрдХ рдиреЛрдЯ рдХреЗ рд▓рд┐рдП рдХрдИ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдЧрд░ рдЖрдкрдХреЛ рдПрдХ рд╢реАрд░реНрд╖рдХ рдФрд░ рдиреЛрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╣рдо рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рджрд┐рдЦрд╛рдПрдВрдЧреЗред
рдПрдХ рд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рдЙрджрд╛рд╣рд░рдг:

 export const config: IFieldsFormMetaModel[] = [ { sectionName: ' ', fieldsForm: [{ name: 'subject', label: '', type: ElementTypes.Text, }], }, { sectionName: '', sectionDescription: '  ', fieldsForm: [{ name: 'reminder', disabled: true, label: '', type: ElementTypes.CheckBox, checked: true, }], }, ]; 

рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, `рдирд╛рдо` рдХреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдорд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдлреЙрд░реНрдорд┐рдХ рдХреЗ рд▓рд┐рдП рдореВрд▓ рдпрд╛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдорд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ 'рдлрд╝реАрд▓реНрдб' рдХреАрдЬрд╝ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдКрдкрд░ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 'рдлрд╝реАрд▓реНрдб' рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 const fields: SomeBusinessApiFields = { subject: '  ', reminder: 'yes', } 

рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпреВрдк рд╕реНрдХреАрдорд╛ рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдХрдВрдЯреЗрдирд░ рдкреНрд░реЙрдкреНрд╕ рдХреЗ рд╕рд╛рде рдлреЙрд░реНрдо рдХреЛ рдлреЙрд░реНрдо рджреЗрддреЗ рд╣реИрдВ, рдмрд╛рд╣рд░реА рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдиреБрд░реЛрдзред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдлреЙрд░реНрдо рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдпреЛрдЬрдирд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ:

 export const CreateClientSchema: ( props: CreateClientProps, ) => Yup.MixedSchema = (props: CreateClientProps) => Yup.object( { subject: Yup.string(), description: Yup.string(), date: dateSchema, address: addressSchema(props), }, ); 

рд░реЗрдВрдбрд░ рдФрд░ рдлрд╝реАрд▓реНрдб рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди


рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдХреБрдВрдЬреА рджреНрд╡рд╛рд░рд╛ рддреНрд╡рд░рд┐рдд рдЦреЛрдЬ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдХреНрд╢рд╛ рдмрдирд╛рдпрд╛ред рдпрд╣ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдЦреЛрдЬ `рд╕реНрд╡рд┐рдЪ` рд╕реЗ рддреЗрдЬрд╝ рд╣реИред

 fieldsMap: Record< ElementTypes, ( state: FormikFieldState, handlers: FormikHandlersState, field: IFieldsFormInfo, ) => JSX.Element > = { [ElementTypes.Text]: ( state: FormikFieldState, handlers: FormikHandlersState, field: IFieldsFormInfo ) => { const { values, errors, touched } = state; return ( <FormTextField key={field.name} element={field} handleChange={this.handleChangeField(handlers.setFieldValue, field.name)} handleBlur={handlers.handleBlur} value={values[field.name]} error={touched[field.name] && errors[field.name] || ''} /> ); }, [ElementTypes.TextSearch]: (...) => {...}, [ElementTypes.TextArea]: (...) => {...}, [ElementTypes.Date]: (...) => {...}, [ElementTypes.CheckBox]: (...) => {...}, [ElementTypes.RadioButton]: (...) => {...}, [ElementTypes.Select]: (...) => {...}, }; 

рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдлрд╝реАрд▓реНрдб рд╕реНрдЯреЗрдЯрдлреБрд▓ рд╣реИред рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ рдФрд░ `React.memo` рдореЗрдВ рд▓рд┐рдкрдЯрд╛ рд╣реИред рдЕрдирд╛рд╡рд╢реНрдпрдХ рд░реЗрдВрдбрд░рд░ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕рд╣рд╛рд░рд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, `рдмрдЪреНрдЪреЛрдВ` рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рддреЗ рд╣реБрдПред

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


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

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


All Articles