Я пытаюсь следовать шаблону проектирования в https://github.com/reactjs/rfcs/issues/26 (см. Ответы bvaughn) и создать редактируемую форму ReactJS, которая читает данные с сервера, отображает их в полях формы и позволяет использовать для редактирования значений.а затем сохранить эти данные обратно в базу данных.
У меня есть некоторый необходимый код:
const mapStateToProps = state => {
return {
invoice: state.invoice,
invoiceReady: state.invoiceReady,
};
};
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.match.params.id !== prevState.id) {
return update(
prevState, {
['id']: {$set: nextProps.match.params.id},
['invoiceReady']: {$set: false}
});
} else {
return update(
prevState, {
['invoice']: {$set: nextProps.invoice},
['invoiceReady']: {$set: nextProps.invoiceReady}
});
}
}
handleChange(event) {
const state = update(
this.state, {
invoice: {
[event.target.id]: {$set: event.target.value}
}
}
);
this.setState(state);
}
componentDidMount() {
this.requestInvoice();
}
componentDidUpdate(prevProps, prevState) {
if (!this.state.invoiceReady) {
this.requestInvoice();
}
}
, и мой JSX-код содержит редактируемые поля, такие как:
<input
type="text"
className="form-control"
id="invoiceDate"
value={this.state.invoice.invoiceDate}
onChange={this.handleChange}
/>
Итак, согласно указанному шаблону я инициируюзапрос к серверу с помощью requestInvoice
, некоторые другие компоненты обрабатывают это действие, получают и сохраняют счет-фактуру в хранилище Redux, поэтому эти данные автоматически записываются в переменную props.invoice
, и я в дальнейшем пишу props.invoice
в this.state.invoice
на getDerivedStateFromProps
для дальнейшей локальной обработки данных счета.При работе с формой вызываются события handleChange
и с помощью immutability-helper (функция обновления) обновленные поля записываются в новое состояние и вызывается setState
.
Моя проблема в том, что во время вызова setState
React вызывает getDerivedStateFromProps
, и поэтому props.invoice
перезаписывает любые изменения, поступающие от пользователя и обрабатываемые в функции handleChange:setState
.
Итак - как решить эту проблему: конфликт между setState
и getDerivedStateFromProps
?
Возможны несколько вариантов:
- myдизайн может быть ошибочным.Например, может быть, я не должен пытаться переместить
props.invoice
в this.state.invoice
(почему бы и нет?)?Но с другой стороны было бы неплохо сохранить счет в this.state и быть уверенным, что все изменения применяются к this.state.invoice
во время редактирования счета. - mybe, я должен предотвратить выполнение
getDerivedStateFromProps
во время setState
?
Может быть, какой-то другой шаблон или код дизайна больше подходит для моей формы ReactJS?
Я использую ReactJ 16.x