I am trying to follow the design pattern in https://github.com/reactjs/rfcs/issues/26 (see replies by bvaughn) and create ReactJS editable form, that reads data from the server, show then in the form fields, allows the use to edit values and then save those data back in database.
I have some essential code:
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();
}
}
and my JSX code contains editable fields like:
<input
type="text"
className="form-control"
id="invoiceDate"
value={this.state.invoice.invoiceDate}
onChange={this.handleChange}
/>
So - according to the mentioned pattern I am initiating the request to the server by requestInvoice
, some other components handle this action and receives and saves the invoice into the Redux store and that is why those data are automatically written into the props.invoice
variable and I am further writing props.invoice
into this.state.invoice
by getDerivedStateFromProps
for further local processing of the invoice data. During the work with the form the handleChange
events are raised and with the help of immutability-helper (update function) the updated fields are written into new state and setState
is called.
My problem is that during the setState
call the React is calling getDerivedStateFromProps
and so the props.invoice
overwrites any changes that are coming from the user and that ar processed into handleChange:setState
function.
So - how to solve this problem: the conflict between setState
and getDerivedStateFromProps
?
Several options may be:
- my design can be flawed. E.g. maybe I should not try to move
props.invoice
intothis.state.invoice
(why not?)? But from the other side it would be nice to save invoice into this.state and be sure that all the changes are applied to thethis.state.invoice
during the editing of the invoice. - mybe I should prevent execution of
getDerivedStateFromProps
duringsetState
?
Maybe some other design pattern or code is more suitable for my ReactJS form?
I am using ReactJ 16.x