Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Multiple updating state which is an object in functional component

How should i update properties of some object in state, if i dont know exactly which properties i want to update, i get these properties from the arguments of a function, and argument is an array of keys i want to update. Here what i try to do, but 2nd updateObj() call overwrites changes (but i want changes should merge):

let newObj = {
    a: 1,
    b: 2,
    c: 3,
}
let [obj, setObj] = React.useState(newObj)

function updateObj(keys, values) {
    let key, newProps = [], updatedValues = {}
    for (let k = 0; k < keys.length; k++) {
        key = keys[k]
        newProps.push(obj[key] + values[k])
    }

    keys.forEach((key, index) => {
        updatedValues[key] = newProps[index]
    })

    setObj(prevState => {
        return {...prevState, ...updatedValues}
    })
}

function changeState() {
    updateObj(['a', 'c'], [1, 1])//add 1 to a and 1 to c
    updateObj(['a', 'b', 'c'], [-1, 1, -1])//add -1 to a, 1 to b and 1 to c
    //in the end i want to get {a: 1, b: 3, c: 3}
}

React.useEffect(() => {console.log(obj)}, [obj])

return (
    <someComponent onMouseDown={()=>changeState()}/>//state updating here
)

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You can use Array.reduce() to create a new object based on prevState:

function updateObj(keys, values) {
  setObj(prevState => 
    keys.reduce((acc, key, index) => ({
      ...acc,
      [key]: acc[key] + values[index]
    }), prevState)
  )
}

Another options is create a new object from keys and values and then merge the two objects:

function updateObj(keys, values) {
  setObj(prevState => ({
    ...prevState,
    ...Object.fromEntries(keys.map((key, index) => 
      [key, values[index]]
    )
  }))
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading