简体   繁体   中英

How to modify an object property in React

I have an object that takes the following form:

booking Object {
  "2019-11-29": Object {
    "selected": true,
  },
  "2019-11-30": Object {
    "selected": true,
  },
}

that I want to modify through invoking a function. More specifically, I want to toggle the selected property, which is Boolean.

I want to invoke a function that 1) checks to see if a certain key exists in the object, "2019-11-29" in this example, and if it does, 2) toggle the selected property, while everything else in the object remain the same.

My following code toggles the selected property temporarily, but doesn't save it in the state.

    const [selected, setSelected] = useState([])    
    const [booking, setBooking] = useState({})    

    const select = day => {
        let markedDay = day.dateString

        // first checks in the "selected" array to see if the "markedDay" exists
        if(selected.includes(markedDay)){
            // toggles the property within the "booking" object
            booking[markedDay] = {
                selected: !booking[markedDay].selected
            }

            setBooking(booking) // this hook doesn't update the state with the newly toggled object property
        }

        // saves the "markedDay" into a new array if it doesn't exist in the array already
        const newSelected = [...selected, markedDay];

        // assigns the property "selected" to the newly entered date and combines it with the pre-existing object
        let obj = newSelected.reduce((c, v) => Object.assign(c, {
          [v]: {
            selected: true,
          }
        }), {})
        setSelected(newSelected)
        setBooking(obj);
    }

What I mean by temporarily is that when I console log the booking object right after the booking[markedDay].selected has been toggled, it will show that the property shows as false , which is the intended result. However, if I were to console log booking outside of the if statement, the global state still shows the property as true .

PS I have mistakenly named the array state selected of the useState the same as the property of the object selected , but they are unrelated.

You're directly modifying the state, that's why the updates aren't reflected in the component. To achieve what you want you can use functional form of setState and object spread:

 if (selected.includes(markedDay)) {
   setBooking(currentBooking => {
     return {
       ...currentBooking,
       [markedDay]: {
         ...currentBooking[markedDay],
         selected: !currentBooking[markedDay].selected
       }
     }
   })
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM