Reputation: 1079
I have the following declaration:
constructor(props) {
super(props);
this.state = {
productArray: [{
barcode: '',
name: ''
}],
numberOfRecords: '',
return_code: '',
return_string: ''
};
}
My hope is to reference the state fields like this:
this.state.productArray[0].barcode and this.state.productArray[1]
I also have a piece of code where I try to update the state. The code looks like this:
for (counter=0;counter<numberOfRecords;counter++) {
currentComponent.setState({productArray[counter].barcode: tempData.barcode[counter]});
currentComponent.setState({productArray[counter].name: tempData.name[counter]});
}
This does not compile and the error is pointing to the first setState command. The compiler is pointing at the [ in the reference to productArray[counter].barcode saying it expected a ','.
Am I defining the state correctly? If not, what would the proper syntax be? If yes, what is proper syntax to reference the individual state field pieces?
Upvotes: 1
Views: 1036
Reputation: 12637
As for the data, I am picking off specific pieces of the tempData array
and
I can remove numberOfRecords from state and get it from tempData.length.
Ok, so productArray
contains a subset of properties of the objects from tempData
, and not a subset of items.
Then I'd not even bother trying to copy the values over and simply map the new values.
currentComponent.setState({
productArray: tempData.map(item => {
const {barcode, name} = item;
return {barcode, name};
})
});
//or in short
currentComponent.setState({
productArray: tempData.map(({barcode, name}) => ({barcode, name}))
});
To answer your question; If you want to access and update some nested property, you should go with a update-function in setState()
so ALL previous updates have been applied to this.state
BEFORE your code tries to modify it.
Something like this:
currentComponent.setState((state) => {
for(let i = 0; i<tempData.length; ++i){
let from = tempData[i], to = state.productArray[i];
to.name = from.name;
to.barcode = from.barcode;
}
return state;
});
The downside/flaw of this approach is, that doesn't deal with the situations where tempData.length !== state.productArray.length
.
Upvotes: 0
Reputation: 8102
The recommended way to updated nested array of objects is to utilize the power of Object.assign
. Keep in mind, that Object.assign will not perform a deep cloning, since it only copies property values,
this.setState({
productArray: Object.assign({}, this.state.productArray[0], {
barcode: 'any value',
})}, ()=>{
console.log(this.state)
}
);
In your case, that's how you can achieve this with shorthand notation:
for (var counter = 0; counter < 1; counter++) {
this.setState({
productArray: Object.assign({}, this.state.productArray[counter], {
barcode: tempData.barcode[counter],
name: tempData.name[counter]
})}, ()=>{
console.log(this.state)
}
);
}
Upvotes: 0
Reputation: 3830
Ideally you only need a single call to setState
something you can do is create a temporary variable where to store the computation such as
const { productArray, numberOfRecords } = this.state;
const newProducts = [ ... productArray ];
for( let counter = 0; counter < numberOfRecords; counter ) {
const item = newProducts[ counter];
newProducts[ counter] = { ...item, barcode: 'value' },
}
this.setState({ productArray: newProducts });
By using the spread operator ...
you can create shallow copies of objects and arrays.
Upvotes: 1
Reputation: 11
you can't directly immutate the state please do it as
let tempvar = this.state.productArray;
for (counter=0;counter<numberOfRecords;counter++) {
tempvar[counter].barcode= newValue
}
this.setState({productArray:tempvar})
Upvotes: 0