I've got an form with different inputs that populates the next state defined like
const [userTaxData, setUserTaxData] = React.useState({
businessName: "",
rfc: "",
address: {
street: "",
number: 0,
suburb: "",
city: "",
state: "",
country: "",
zcode: 0
}
});
and the handleChange function defined like
const handleChange = (e) => {
setUserTaxData({
...userTaxData,
[e.target.name]: e.target.value
});
};
But the problema I've faced is that when I try to change the "zcode" property it is not working and it is because is inside the "address" object, so I need you support because I don't know how to access to "address" properties.
CodePudding user response:
I think zcode is a widow object or proto a method on the proto widow object
businessName.address.zcode
CodePudding user response:
You can't update nested object states with string keys, however if you flatten the object, you can.
Example:
const flattenObject = (obj) => Object.assign({}, ... function _flatten(o) {
return [].concat(...Object.keys(o).map(k => typeof o[k] === 'object' ? _flatten(o[k]) : ({
[k]: o[k]
})))
}(obj))
const unflattenObject = (obj) => {
var result = {}
for (var i in data) {
var keys = i.split('.')
keys.reduce(function(r, e, j) {
return r[e] || (r[e] = isNaN(Number(keys[j 1])) ? (keys.length - 1 == j ? data[i] : {}) : [])
}, result)
}
return result
}
const handleChange = (e) => {
const flattened = flattenObject(userTaxData)
flattened[e.target.name] = e.target.value
const unflattened = unflattenObject(flattened)
setUserTaxData(unflattened);
};
(Flattening code taken from this SO post, unflattening code taken from this SO post)
CodePudding user response:
A simple way to do it is to test if you have update inside address property or not :
const handleChange = (e) => {
if (Object.keys(userTaxData.address).includes(e.target.name)) {
setUserTaxData({
...userTaxData,
address: { ...userTaxData.address, [e.target.name]: e.target.value },
});
} else {
setUserTaxData({
...userTaxData,
[e.target.name]: e.target.value,
});
}
};