Reputation: 3417
When supplier._id
changes, the componentDidUpdate
doesn't recognise the update. Is this because it's nested? What am I missing here?
Path: React.js
constructor(props) {
super(props);
this.state = {
supplier: {
_id: '',
name: ''
}
};
this.handleUpdateForm = this.handleUpdateForm.bind(this);
}
componentDidUpdate(prevProps, prevState) {
const { supplier } = this.state;
if (prevState.supplier._id !== supplier._id) {
console.log('Supplier id changed');
}
}
handleUpdateForm(fieldsToUpdate, inputName, inputValue) {
let { supplier, suppliers } = this.state;
if (fieldsToUpdate === 'supplierFields') {
if (inputName === 'supplier_id') {
const selectedSupplier =
inputName === 'supplier_id'
? suppliers.find((supplier) => supplier._id === inputValue)
: null;
supplier = Object.assign(supplier, selectedSupplier);
} else {
supplier._id = inputName === 'name' ? '' : supplier._id;
supplier = Object.assign(supplier, {
[inputName]: inputValue
});
}
}
this.setState({
supplier
});
}
Upvotes: 1
Views: 118
Reputation: 1723
The issue is in this part of code
supplier = Object.assign(supplier, {
[inputName]: inputValue
});
Object.assign takes the first parameter as target and the rest are sources, means 1st parameter object reference will be taken so you're updating the supplier object directly and that's why it's not calling componentDidUpdate. try this -
supplier = Object.assign({}, supplier, {
[inputName]: inputValue
});
By above snippet a new object will be created
Upvotes: 0
Reputation: 202696
In supplier = Object.assign(supplier, selectedSupplier);
, supplier
is the state reference. You "merge" selectedSupplier
into that referenced object. This mutates the state object, supplier
. Object.assign
returns the target object, which you save back to supplier
, and then update state. The object reference for supplier
never changes.
supplier
state then updatehandleUpdateForm(fieldsToUpdate, inputName, inputValue) {
let { supplier, suppliers } = this.state;
if (fieldsToUpdate === 'supplierFields') {
if (inputName === 'supplier_id') {
const selectedSupplier =
inputName === 'supplier_id'
? suppliers.find((supplier) => supplier._id === inputValue)
: null;
if (selectedSupplier) {
supplier = {
...supplier, // <-- shallow copy existing state
...selectedSupplier, // <-- merge new supplier data
};
}
} else {
supplier = {
...supplier, // <-- shallow copy existing state
_id: inputName === 'name' ? '' : supplier._id // <-- update property
[inputName]: inputValue, // <-- merge input update
};
}
}
this.setState({
supplier
});
}
Upvotes: 2
Reputation: 1430
Most likely the issue lies in how you are setting the state and how you are extracting the values of the state. Since you are using
this.setState({
supplier
});
you are not merging the state with your supplier
property. So your state is bound to look like this after using setState
:
state = {
_id: "XXXXXXXXX",
name: "XXXXXXXX",
supplier:{
_id: '',
_name: ''
}
}
So, in order to fix this, you should change your setState
to immutably set state on the supplier
property like:
this.setState({
supplier: {...supplier}
});
The main thing to remember is, setState
merges whatever changes you put in for a property with the rest of the state.
Upvotes: 0