рдкрд░рд┐рдЪрдп
React.js рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рдореБрдЭреЗ рдЕрдХреНрд╕рд░ рдлреЙрд░реНрдо рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд╕реЗ рдирд┐рдкрдЯрдирд╛ рдкрдбрд╝рддрд╛ рдерд╛ред Redux-Form , React-Redux-Form рдореЗрд░реЗ рд╣рд╛рдереЛрдВ рд╕реЗ рд╣реЛрдХрд░ рдЧреБрдЬрд░рд╛, рд▓реЗрдХрд┐рди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдиреЗ рднреА рдореБрдЭреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрддреБрд╖реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдореБрдЭреЗ рдпрд╣ рдкрд╕рдВрдж рдирд╣реАрдВ рдерд╛ рдХрд┐ рдлреЙрд░реНрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ reducer рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдПрдХреНрд╢рди рдХреНрд░рд┐рдПрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреБрдЬрд░рддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рджрд╛рди рдЕрдмреНрд░рд╛рдореЛрд╡ рдХреЗ рдЕрдиреБрд╕рд╛рд░, "рдлрд╝реЙрд░реНрдо рдХреА рд╕реНрдерд┐рддрд┐ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдЕрд▓реНрдкрдХрд╛рд▓рд┐рдХ рдФрд░ рд╕реНрдерд╛рдиреАрдп рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕реЗ Redux (рдпрд╛ рдХрд┐рд╕реА рднреА рдлрд╝реНрд▓рдХреНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА) рдореЗрдВ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред"
рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рд░рд┐рдПрдХреНрдЯ- рд░рд┐рдбреНрдпреВрдХреНрд╕ -рдлреЙрд░реНрдо рдореЗрдВ рдПрдХ рд▓реЛрдХрд▓рдлреЙрд░реНрдо рдШрдЯрдХ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдмрд┐рдирд╛ рд░рд┐рдбрдХреНрд╕ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣ 21.9kB рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рдЖрдзреЗ рд╕реЗ рдХрдо рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИред
рдореИрдВ рдирд╛рдорд┐рдд рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рдЦрд┐рд▓рд╛рдл рдирд╣реАрдВ рд╣реВрдВ, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╡реЗ рдЕрдкреВрд░рдгреАрдп рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдХрд┐рд╕реА рддреГрддреАрдп-рдкрдХреНрд╖ рдШрдЯрдХ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЕрд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдкрдиреЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЙрди рд░реВрдкреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рд░реЗрдбрдХреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдореИрдВрдиреЗ рдШрдЯрдХ рдХреА рд╕реНрдерд╛рдиреАрдп рд╕реНрдерд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛, рдФрд░ рдирдИ рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рдЙрддреНрдкрдиреНрди рд╣реБрдИрдВ: рдХреЛрдб рдХреА рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рд╣реБрдИ, рдШрдЯрдХреЛрдВ рдиреЗ рдкрдардиреАрдпрддрд╛ рдЦреЛ рджреА, рдмрд╣реБрдд рдЕрдзрд┐рдХ рджреЛрд╣рд░рд╛рд╡ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ред
рд╕рдорд╛рдзрд╛рди рдЙрдЪреНрдЪ рдЖрджреЗрд╢ рдШрдЯрдХ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдереАред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, HOC рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдПрдХ рдШрдЯрдХ рдЗрдирдкреБрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдпрд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдкреНрд░реЙрдкреНрд╕ рдХреЗ рдПрдХреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдЕрджреНрдпрддрди рдХрд░рддрд╛ рд╣реИред рдЖрдзрд┐рдХрд╛рд░рд┐рдХ React.js рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ HOC рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдкрдврд╝реЗрдВред HOC рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдШрдЯрдХ рдХреЛ рджреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдерд╛, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛, рдФрд░ рджреВрд╕рд░рд╛ - рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдПред
рд░реВрдк рд░рдЪрдирд╛
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдПрдХ рд╕рд░рд▓ рдлреАрдбрдмреИрдХ рдлреЙрд░реНрдо рдмрдирд╛рдПрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ 3 рдлрд╝реАрд▓реНрдб рд╣реЛрдВрдЧреЗ: рдирд╛рдо, рдИрдореЗрд▓, рдлреЛрдиред
рд╕рд░рд▓рддрд╛ рдХреЗ рд▓рд┐рдП рд╣рдо Create-React-App рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕реЗ рд╡рд┐рд╢реНрд╡ рд╕реНрддрд░ рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
npm i -g create-react-app
рдлрд┐рд░ рд╢реБрджреНрдз-рдлрд╝реЙрд░реНрдо рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЕрдкрдирд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдПрдВ
create-react-app pure-form
рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдкреНрд░реЛрдк-рдкреНрд░рдХрд╛рд░ рдФрд░ рд╡рд░реНрдЧрдирд╛рдо рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рд╡реЗ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдВрдЧреЗ:
npm i prop-types classnames -S
рджреЛ рдлрд╝реЛрд▓реНрдбрд░ / рдШрдЯрдХ рдФрд░ / рдХрдВрдЯреЗрдирд░ рдмрдирд╛рдПрдБред / рдШрдЯрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╕рднреА рдШрдЯрдХ рд╣реЛрдВрдЧреЗред / рдХрдВрдЯреЗрдирд░ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, рддрд░реНрдХ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдШрдЯрдХред
/ рдШрдЯрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, рдПрдХ Input.jsx рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╕рднреА рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдШрдЯрдХ рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рд╕реНрддрд░ рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдкреНрд░реЙрдкрдЯреАрдкрд╛рдЗрдкреНрд╕ рдФрд░ рдбрд┐рдлреЙрд▓реНрдЯрдкреНрд░реЙрдкреНрд╕ рдХреЛ рдХреНрд╡реЙрд▓рд┐рдЯреА рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рд┐рд╕реНрдХреНрд░рд╛рдЗрдм рдХрд░рдирд╛ рди рднреВрд▓реЗрдВ, рдХрд╕реНрдЯрдо рдХреНрд▓рд╛рд╕реЗрд╕ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдкреНрд░рджрд╛рди рдХрд░реЗрдВ, рдФрд░ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ PureComponent рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рднреА рдХрд░реЗрдВред
рдкрд░рд┐рдгрд╛рдо рд╣реИ:
import React, { PureComponent } from 'react'; import cx from 'classnames'; import PropTypes from 'prop-types'; class Input extends PureComponent { render() { const { name, error, labelClass, inputClass, placeholder, ...props } = this.props; return ( <label className={cx('label', !!labelClass && labelClass)} htmlFor={`id-${name}`} > <span className="span">{placeholder}</span> <input className={cx( 'input', !!inputClass && inputClass, !!error && 'error' )} name={name} id={`id-${name}`} onFocus={this.handleFocus} onBlur={this.handleBlur} {...props} /> {!!error && <span className="errorText">{error}</span>} </label> ); } } Input.defaultProps = { type: 'text', error: '', required: false, autoComplete: 'off', labelClass: '', inputClass: '', }; Input.propTypes = { value: PropTypes.string.isRequired, name: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, placeholder: PropTypes.string.isRequired, error: PropTypes.string, type: PropTypes.string, required: PropTypes.bool, autoComplete: PropTypes.string, labelClass: PropTypes.string, inputClass: PropTypes.string, }; export default Input;
рдЗрд╕рдХреЗ рдмрд╛рдж, / рдШрдЯрдХреЛрдВ рдХреЗ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВред Form.jsx , рдЬрд┐рд╕рдореЗрдВ рдлрд╛рд░реНрдо рд╡рд╛рд▓рд╛ рдШрдЯрдХ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╣рдо рдкреНрд░реЙрдкрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ, рд╕рд╛рде рд╣реА рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдореВрд▓реНрдп , рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдВ рд░рд╛рдЬреНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Input from './Input'; import FormWrapper from '../containers/FormWrapper'; class Form extends Component { render() { const { data: { username, email, phone }, errors, handleInput, handleSubmit, } = this.props; return ( <div className="openBill"> <form className="openBillForm" onSubmit={handleSubmit}> <Input key="username" value={username} name="username" onChange={handleInput} placeholder="" error={errors.username} required /> <Input key="phone" value={phone} name="phone" onChange={handleInput} placeholder="" error={errors.phone} required /> <Input key="email" value={email} type="email" name="email" onChange={handleInput} placeholder=" " error={errors.email} required /> <button type="submit" className="submitBtn"> </button> </form> </div> ); } } Form.propTypes = { data: PropTypes.shape({ username: PropTypes.string.isRequired, phone: PropTypes.string.isRequired, email: PropTypes.string.isRequired, }).isRequired, errors: PropTypes.shape({ username: PropTypes.string.isRequired, phone: PropTypes.string.isRequired, email: PropTypes.string.isRequired, }).isRequired, handleInput: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired, }; export default FormWrapper(Form);
HOC рдирд┐рд░реНрдорд╛рдг
/ рдХрдВрдЯреЗрдирд░ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, FormWrapper.jsx рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБред рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдВрджрд░ рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд░реИрдкреНрдбрдХрдВрдкреЛрдиреЗрдВрдЯ рдШрдЯрдХ рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рд░реИрдкреНрдбрдлрд╝реЙрд░реНрдо рдХреНрд▓рд╛рд╕ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╡рд░реНрдЧ рдХрд╛ рд░реЗрдВрдбрд░ рдореЗрдердб WrappedComponent рдХреЛ рдкреНрд░реЙрдкреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рддрд╛ рд╣реИред рдХреНрд▓рд╛рд╕рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рдпрд╣ рдбрд┐рдмрдЧрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рд░рд▓ рдХрд░реЗрдЧрд╛ред
рд░реИрдкреНрдбрдлрд╝реЙрд░реНрдо рдХреНрд▓рд╛рд╕ рдореЗрдВ , рд╕реНрдерд┐рддрд┐ рдмрдирд╛рдПрдБ: isFetching - рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдзреНрд╡рдЬ, рдбреЗрдЯрд╛ - рдЗрдирдкреБрдЯ рдорд╛рдиреЛрдВ, рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╡рд╛рд▓реА рдПрдХ рд╡рд╕реНрддреБ - рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╕реНрддреБред рдШреЛрд╖рд┐рдд рд░рд╛рдЬреНрдп рдХреЛ рд░реИрдкреНрдбрдХрдореНрдкреЛрдиреЗрдВрдЯ рдореЗрдВ рднреЗрдЬ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдКрдкрд░реА рд░рд╛рдЬреНрдпреЛрдВ рдореЗрдВ рдкреНрд░рдкрддреНрд░ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рдкрдардиреАрдп рдФрд░ рдкрд╛рд░рджрд░реНрд╢реА рдмрдирд╛рддрд╛ рд╣реИред
export default function Wrapper(WrappedComponent) { return class FormWrapper extends Component { state = { isFetching: false, data: { username: '', phone: '', email: '', }, errors: { username: '', phone: '', email: '', }, }; render() { return <WrappedComponent {...this.state} />; } }; }
рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдЖрд╡рд░рдг рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдк рдЗрд╕ рдкреНрд░рдгрд╛рд▓реА рдХреЛ рд╕реБрдзрд╛рд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ HOC рдХреЛ рдПрдХ рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдПрдореНрдмреЗрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдорд╛рдиреЛрдВ рдХреЛ рдмрдирд╛рдПрдЧрд╛ред
import React, { Component } from 'react'; export default function getDefaultValues(initialState, requiredFields) { return function Wrapper(WrappedComponent) { return class WrappedForm extends Component { state = { isFetching: false, data: initialState, errors: requiredFields, }; render() { return <WrappedComponent {...this.state} {...this.props} />; } }; }; }
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдЖрдк рди рдХреЗрд╡рд▓ рд░рд╛рдЬреНрдп рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рдЖрдо рддреМрд░ рдкрд░ рдХрд┐рд╕реА рднреА рдкреИрд░рд╛рдореАрдЯрд░ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдФрд░ рд╡рд┐рдзрд┐рдпрд╛рдБ, рдЬрд┐рдирдХреЗ рдЖрдзрд╛рд░ рдкрд░ Form.jsx рдореЗрдВ рдПрдХ рдлреЙрд░реНрдо рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╖рдп рд╣реЛрдЧрд╛ред
Form.jsx рдлрд╝рд╛рдЗрд▓ рдореЗрдВ , рд╣рдо рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд░рд╛рдЬреНрдп рдорд╛рдиреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ HOC рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ:
const initialState = { username: '', phone: '', email: '', }; export default FormWrapper(initialState, initialState)(Form);
рдЪрд▓реЛ рдЗрдирдкреБрдЯ рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдорд╛рдиреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд▓ рдЗрдирдкреБрдЯ рд╡рд┐рдзрд┐ рдмрдирд╛рддреЗ рд╣реИрдВред рд╡рд╣ рдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рд╣рдо рдореВрд▓реНрдп рдФрд░ рдирд╛рдо рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рд╣рдо рдЙрдиреНрд╣реЗрдВ рд╕реЗрдЯрд╕реНрдЯреИрдЯ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдЗрдирдкреБрдЯ рдорд╛рди рдбреЗрдЯрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реЗрдЯрд╕реНрдЯреИрдЯ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд╕рд╛рде рд╣реА рдкреНрд░рд╛рдкреНрдд рдореВрд▓реНрдп рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд╕рд╛рде, рд╣рдо рдЪрд░ рдХреНрд╖реЗрддреНрд░ рдХреЗ рддреНрд░реБрдЯрд┐ рднрдВрдбрд╛рд░рдг рдХреЛ рд╢реВрдиреНрдп рдХрд░рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:
handleInput = event => { const { value, name } = event.currentTarget; this.setState(({ data, errors }) => ({ data: { ...data, [name]: value, }, errors: { ...errors, [name]: '', }, })); };
рдЕрдм рд╣рдо рдлреЙрд░реНрдо рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдбрд╕рдмрдорд┐рдЯ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВрдЧреЗ , рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рд╣рдореЗрдВ рд╕рддреНрдпрд╛рдкрди рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдо рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдлрд╝реАрд▓реНрдб рдХреЛ рдорд╛рдиреНрдп рдХрд░реЗрдВрдЧреЗ, рдЕрд░реНрдерд╛рдд, рдЗрд╕ .state.errors рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╕рднреА рдХреБрдВрдЬрд┐рдпрд╛рдБред рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:
handleSubmit = e => { e.preventDefault(); const { data } = this.state; const isValid = Object.keys(data).reduce( (sum, item) => sum && this.validate(item, data[item]), true ); if (isValid) { console.log(data); } };
рдХрдо рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЙрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░, рдорд╛рдиреНрдп рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдирд╛рдо , рдореВрд▓реНрдп рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рд╡рд┐рдзрд┐ рдХреЗ рдЕрдВрджрд░, рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рддреА рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдмреВрд▓рд┐рдпрди рдкреНрд░рдХрд╛рд░ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдЬреЛрдбрд╝реА рдорд╛рди рд╕рддреНрдпрд╛рдкрди рдкрд╛рд╕ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЕрдорд╛рдиреНрдп рд╡реИрд░рд┐рдПрдмрд▓ рдЧрд▓рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдбреЗрдЯрд╛ рдХрдВрд╕реЛрд▓ рдкрд░ рдЖрдЙрдЯрдкреБрдЯ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЕрд░реНрдерд╛рдд рдлреЙрд░реНрдо рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓рд╛ рдпрд╣рд╛рдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ - рдПрдХ рдЧреИрд░-рдЦрд╛рд▓реА рдлреЙрд░реНрдо рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрдХред рдорд╛рдиреНрдп рд╡рд┐рдзрд┐:
validate = (name, value) => { if (!value.trim()) { this.setState( ({ errors }) => ({ errors: { ...errors, [name]: ' ', }, }), () => false ); } else { return true; } };
рджреЛрдиреЛрдВ рд╣реИрдВрдбрд▓ рдФрд░ рд╣реИрдВрдбрд▓рдЗрдиреНрдкреБрдЯ рдкрджреНрдзрддрд┐рдпреЛрдВ рдХреЛ рд▓рд┐рдкрдЯрд╛ рдХреЗ рдкрд╛рд╕ рднреЗрдЬрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
render() { return ( <WrappedComponent {...this.state} {...this.props} handleInput={this.handleInput} handleSubmit={this.handleSubmit} /> ); }
рдирддреАрдЬрддрди, рд╣рдореЗрдВ рд╕рд░рд▓ рд╕рддреНрдпрд╛рдкрди рдФрд░ рддреНрд░реБрдЯрд┐ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд╛рде рдПрдХ рддреИрдпрд╛рд░ рдлреАрдбрдмреИрдХ рдлреЙрд░реНрдо рдорд┐рд▓рддрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рд╣рдордиреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдШрдЯрдХ рд╕реЗ рддрд╛рд░реНрдХрд┐рдХ рднрд╛рдЧ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ред
рдирд┐рд╖реНрдХрд░реНрд╖
рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд░реВрдкреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдЪрдУрд╕реА рдмрдирд╛рдиреЗ рдХреЗ рдореВрд▓ рдЙрджрд╛рд╣рд░рдг рдХреЛ рджреЗрдЦрд╛ред рдлреЙрд░реНрдо рдмрдирд╛рддреЗ рд╕рдордп, рдХреЗрд╡рд▓ рд╕рд░рд▓ рдЗрдирдкреБрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдмрд┐рдирд╛ рдЬрдЯрд┐рд▓ рддрддреНрд╡реЛрдВ рдХреЗ, рдЬреИрд╕реЗ рдбреНрд░реЙрдк-рдбрд╛рдЙрди рд╕реВрдЪреА, рдЪреЗрдХрдмреЙрдХреНрд╕, рд░реЗрдбрд┐рдпреЛ рдмрдЯрди рдФрд░ рдЕрдиреНрдпред рдпрджрд┐ рдЙрдкрд▓рдмреНрдз рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдИрд╡реЗрдВрдЯ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред
рд▓реЗрдЦ рдореЗрдВ рдпрд╛ рдореЗрд░реЗ рдореЗрд▓ рдкрд░ рдкреНрд░рд╢реНрдиреЛрдВ рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рд▓рд┐рдЦреЗрдВред
рдПрдХ рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рд╢реБрджреНрдз рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд░реВрдк ред
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!