1

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.

3
  • What is the value of e.target.name? Is it address, or zcode, or something else? Commented Mar 15, 2022 at 21:17
  • zcode because I am on zcode input Commented Mar 15, 2022 at 21:24
  • How do you "know" that you should be modifying the zcode property of the address object, and not some other property like on the base object itself? Commented Mar 15, 2022 at 21:32

2 Answers 2

4

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,
      });
    }
  };
Sign up to request clarification or add additional context in comments.

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.