-
-
Save afitiskin/a65c26ff923d13788980 to your computer and use it in GitHub Desktop.
import React, { Component, PropTypes } from 'react'; | |
export default class CreditCardField extends Component { | |
static propTypes = { | |
value: PropTypes.string, | |
onChange: PropTypes.func, | |
} | |
static defaultProps = { | |
value: '' | |
} | |
render() { | |
// we receive from parent value like 5555555555554444 | |
// we transform it to view value 5555 5555 5555 4444 | |
// and display this view value | |
const value = this.applyFormat(this.props.value); | |
return ( | |
<input {...this.props} value={value} onChange={this.handleChange} type="text" /> | |
); | |
} | |
handleChange = (e) => { | |
// when user change something | |
// we remove all decorations from value | |
// and send to parent only only digits | |
if (this.props.onChange) { | |
this.props.onChange(this.removeFormat(e.target.value)); | |
} | |
} | |
applyFormat(value = '') { | |
// allow only numbers, add spaces after each 4 character, only 16 digits | |
return value.replace(/[^0-9]/g, '').slice(0, 16).match(/.{1,4}/g).join(' '); | |
} | |
removeFormat(value = '') { | |
// leave only 16 digits | |
return value.replace(/[^0-9]/g, '').slice(0, 16); | |
} | |
} |
import React, { Component, PropTypes } from 'react'; | |
import CreditCardField from './credit-card-field'; | |
export default class SomeForm extends Component { | |
state = { | |
creditCardNumber: '' | |
} | |
render() { | |
return ( | |
<CreditCardField value={this.state.creditCardNumber} onChange={this.handleCreditCardChange} /> | |
); | |
} | |
handleCreditCardChange(value) { | |
this.setState({ | |
...this.state, | |
creditCardNumber: value | |
}); | |
} | |
} |
@isnifer, касательно 2 фунций для одного поля: вам так или иначе придется форматировать / очищать от форматирования пользовательский ввод, по другому вы аналогичное поведение реализовать не сможете, ни в реакте, ни используя другую библиотеку / фреймворк.
Stateless компоненты – дефакто стандарт и их использование поможет вам сохранить код чистым и избежать многих проблем.
Касательно большого количества полей и повторения кода: Создается унифицированный FormattedInputField, в который передаются параметрами 2 функции: formatter и cleaner. Тогда вы имеете просто библиотеку функции для форматирования / очистки от форматирования, и собираете вашу форму используя их.
@isnifer, вообще я бы не стал задумываться об оптимизации до того момента, как не столкнулся бы с какими-то проблемами. Собственно если возникнет проблема большого размера результирующего js-файла, то она может быть решена кучей способов, начиная с оптимизации кода (рефакторинг делать проще, когда есть код и видны повторяющиеся участки, требующие оптимизации) до разбивки всего бандла на несколько кусков с загрузкой по требованию. Если же возникнут проблемы с быстродействием – то здесь думать о количестве строк кода нет смысла, оптимизации будут направлены совсем в другое русло.
Две функции для одного поля, одна будет выводить на вьюху форматированную модель, а одна будет брать форматированный вывод и возвращать его обратно в пользовательский ввод и класть в стор.
Первый вопрос - не много ли чести для одного поля?
Второе, а что если полей будет 30-40-50 (а такие кейсы есть, у нас весь проект из форм состоит) и для каждого поля будет какое-то дублирование. Своя константа со значением, поле, а еще две функции для форматирования. Для 50 полей это не менее 200 строк кода.