Значения полей admin-on-rest, redux-form и trimming
На самом деле это меньше вопрос, чем то, что я делюсь своей техникой обрезки значений полей с помощью этой библиотеки. Я читал все сообщения, которые мог найти по этому вопросу на Stack Exchange и в других местах, и не мог найти полное рабочее решение. Мне потребовалось слишком много времени и проб и ошибок, чтобы понять.
С помощью redux-формы вы должны использовать создателя действия изменения, чтобы сбросить значение поля до усеченного значения. Сложной частью было найти правильное место в коде в подходящих условиях, чтобы выполнить обрезку и запустить действие. Я попытался нормализовать метод, включенный с редукс-формой. Нет. Я пытался обрезать поля в пользовательских обработчиках onChange и onBlur. Нет. Большинство попыток решения привело к невозможности ввести пробел в поле. Я думал, что смогу сделать это в собственном обработчике onBlur, но если я отправлю действие изменения в избыточной форме из этого обработчика, то сначала действие изменения обновит состояние, затем последует ожидающее действие размытия и перезапишет обрезанное значение с помощью Первоначальная стоимость в состоянии.
Во всяком случае, вот мое решение.
1) Импортируйте действие изменения избыточной формы и добавьте пользовательский метод в ваш реквизит для его отправки.
import { connect } from 'react-redux';
import { change } from 'redux-form';
const form = 'record-form';
function mapDispatchToProps(dispatch) {
return {
trimFieldValue: (field, value) => {
dispatch(change(form, field, value.trim()));
},
};
}
const enhance = connect(null, mapDispatchToProps);
export default enhance(MyComponent);
2) Следите за фокусировкой поля в локальном состоянии, добавляйте обработчики onFocus и onBlur в поля, которые необходимо обрезать.
в методе рендеринга...
const handleBlur = (event) => {
this.setState({
hasFocus: null
});
}
const handleFocus = (event) => {
this.setState({
hasFocus: event.target.name
});
}
в JSX...
<LongTextInput source="name" onBlur={handleBlur} onFocus={handleFocus} />
<LongTextInput source="description" onBlur={handleBlur} onFocus={handleFocus} />
3) Проверьте необходимость обрезки значений componentDidUpdate() и отправьте действие, чтобы сделать это при необходимости.
componentDidUpdate = (prevProps, prevState) => {
if (this.state && this.state.name && this.state.hasFocus !== 'name' && (this.state.name !== this.state.name.trim())) {
this.props.trimFieldValue('name', this.state.name);
}
if (this.state && this.state.description && this.state.hasFocus !== 'description' && (this.state.description !== this.state.description.trim())) {
this.props.trimFieldValue('description', this.state.description);
}
}
Мой метод componentDidUpdate немного уродлив, но пока работает. Суть в том, что для каждого поля, которое вы тестируете для обрезки, вам ничего не нужно делать, если это поле имеет фокус. Если поле не имеет фокуса, и оно должно быть обрезано, тогда запустите действие, чтобы обновить это поле в форме редукса, используя ваш собственный диспетчер в подпорках.
Возможно, это не должно было занять у меня так много времени, но я нашел это решение нелегким найти. Возможно, такой подход сэкономит кому-то еще время. Я также открыт для обратной связи в духе "ну, почему ты просто не сделал это!" если я что-то пропустил