skip to Main Content

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
)

2

Answers


  1. I would calculate it first and then swap the state object

    function updateObj(keys, values) {
      setObj((prevState) => {
        const newState = { ...prevState };
        for (let i = 0; i < keys.length; i += 1) {
          newState[keys[i]] += values[i];
        }
        return newState;
      });
    }
    
    Login or Signup to reply.
  2. 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 option 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]]
        )
      }))
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search