sg.cc sg.cc -3 years ago 96
React JSX Question

How do I chain state updates?

I have a form with multiple controls that saves everything to a variable. Each control has an

onChanged
function, which runs a state update with that control's new value:

function onChangedValUpdate(newVal){
let fields = clone(this.state.fields);
fields[controlId] = newVal;
this.setState({fields});
}


My controls are dynamically created, and when they are, they run
onChangedValUpdate
on their initial value, if one is present. The problem is, sometimes a lot of controls are created at once, and React queues up its
setState
s using the same cloned
fields
object for each update. The object is not updated between
setState
s, presumably for similar reasons to this question. This means that, effectively, all but one control's updates are overwritten.

I tried writing an over-smart routine which used
setState
's callback to only run it if there isn't one already in progress and remember changes made to the
fields
variable in between
setState
s, but React went and ran all my queued updates simultaneously. Regardless, the routine felt too contrived to be right.

I'm sure this is a trivial and solved problem, but I can't seem to formulate my question in a Googleable way. How do I chain state updates that happen concurrently, and of which there may be any number?

EDIT For posterity, my solution, thanks to Yuri:

function onChangedValUpdate(newVal){
this.setState( state => {
let fields = clone(state.fields);
fields[controlId] = newVal;
return {fields};
}
}

Answer Source

You could pass a mutation function to setState. This will prevent overwritting on batched updates because every callback will get the most recent previous state.

function onChangedValUpdate(newVal){
  this.setState(function(state){
    const fields = clone(state.fields)

    fields[controlId] = newVal

    return {fields: fields}
  });
}

Or using object spread and enhanced object literals.

function onChangedValUpdate(newVal){
  this.setState(({fields}) => ({fields: {...fields, [controlId]: newVal}}));
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download