0

I want to add a new state in object after checked input. Item state is an object with another object inside

const [item, setItem] = useState({
    series: '',
    model: '',
    addons: {
      gps: false,
      wifi: false,
      esim: false,
    },
    price: ''
})

Change series, model on input by value is obvious but how Can I change objects in addons? I can't do this by

onChange={(e) => setItem({ ...item, gps: e.target.checked })}

or

onChange={(e) => setItem({ ...item, addons.gps: e.target.checked })}

Code:

import React, {useState} from "react";
import "./style.css";

export default function App() {
  const [item, setItem] = useState({
    series: '',
    model: '',
    addons: {
      gps: false,
      wifi: false,
      esim: false,
    },
    price: ''
  })


  const sendItem = () => {
    console.log(item, 'add item')
  }
  
  return (
    <div>
      <form onSubmit={sendItem}>
      <div>
       <label htmlFor="series">Series:</label>
              <input
                name="series"
                label="series"
                type="text"
                value={item.series}
                onChange={(e) => setItem({ ...item, series: e.target.value })}
              />
        </div>
        <div>
       <label htmlFor="model">Model:</label>
              <input
                name="model"
                label="model"
                type="text"
                value={item.model}
                onChange={(e) => setItem({ ...item, model: e.target.value })}
              />
        </div>
        <div style={{display: 'flex', flexDirection: 'row', justifyContect: 'center', alignItems: 'center'}}>
       <label htmlFor="addons">Addons:</label>
       <p>GPS:</p>
              <input
                name="gps"
                type="checkbox"
                onChange={(e) => setItem({ ...item, gps: e.target.checked })}
              />
        <p>Wifi:</p>
              <input
                name="wifi"
                type="checkbox"
                onChange={(e) => setItem({ ...item, wifi: e.target.checked })}
              />
         <p>Esim:</p>
              <input
                name="esim"
                type="checkbox"
                onChange={(e) => setItem({ ...item, esim: e.target.checked })}
              />
        </div>
         <div>
       <label htmlFor="price">Price:</label>
              <input
                name="price"
                label="price"
                type="text"
                value={item.price}
                onChange={(e) => setItem({ ...item, price: e.target.value })}
              />
        </div>


        <button type="submit">Send</button>
      </form>
    </div>
  );
}
Abraham
  • 8,525
  • 5
  • 47
  • 53
Arex Speed
  • 177
  • 1
  • 10
  • The reason it doesn't work is because of this: [What is event pooling in react?](https://stackoverflow.com/questions/36114196/what-is-event-pooling-in-react) – Emile Bergeron Feb 10 '21 at 16:08
  • And the spread syntax [explained by @jnpdx](https://stackoverflow.com/a/66140356/1218980) – Emile Bergeron Feb 10 '21 at 16:10
  • You can reference this [https://stackoverflow.com/questions/43638938/updating-an-object-with-setstate-in-react](https://stackoverflow.com/questions/43638938/updating-an-object-with-setstate-in-react) – Akhil G Krishnan Feb 10 '21 at 16:52

1 Answers1

6
setItem({ ...item, addons: {...item.addons, gps: e.target.checked} })

You can spread both item and addons, allowing you to only update the property of addons that you need to change.

jnpdx
  • 45,847
  • 6
  • 64
  • 94