在表单中使用嵌套对象更新状态

Update state with Nested object in Form

我在尝试使用 useState 更新嵌套对象时遇到了一些问题。我有一个表格,用户可以在其中 add/edit 汽车信息。所以基本上我是在本地状态下处理汽车,以表格形式显示数据。

 //Local state to handle a Car
const [car, setCar] = useState({
    brand: "Mazda",
    vin: "JMB838783S",
    location: {
      address: "9098 West Alabama Street",
      lat: "-22.73984",
      long: "8.44538",
    },
    contact: {
      phone: "+16758907676",
      email: "car@provider.com",
    }
  });

然而,当我尝试编辑地址或 phone 的信息时,我无法使用 onChange

中的函数使其工作
const handleInputChanges = e => {

    setCar({
      ...car,
      [e.target.name] : e.target.value
    })
};

表格

<FormContainer onSubmit={handleSubmit}>
            <DropPictureZone onImageDropped={setThumbnailDropped} />

            <InputText
              type="text"
              name="brand"
              placeholder="Brand"
              value={name}
              onChange={handleInputChanges}
            />

            <InputText
              type="text"
              name="address"
              placeholder="Address"
              value={location.address}
              onChange={handleInputChanges}
            />

            <div className="p-grid">
              <div className="p-col">
                <InputText
                  type="text"
                  name="lat"
                  placeholder="Latitude"
                  value={location.lat}
                  onChange={handleInputChanges}
                />
              </div>

            <div className="p-grid">
              <div className="p-col-4">
                <InputMask
                  mask="(xxx)-xxx-xxxx"
                  name="phone"
                  placeholder="Phone Number"
                  value={contact.phone}
                  onChange={handleInputChanges}
                />
              </div>

              <div className="p-col">
                <InputText
                  type="text"
                  name="email"
                  placeholder="Email"
                  value={contact.email}
                  onChange={handleInputChanges}
                />
              </div>
            </div>

            <Button label="Save" />
          </FormContainer>

实现这一目标的正确方法是什么? 谢谢。

这个问题有很多正确答案。这是一个:

修改您的更改处理程序以接受一个 curried 参数,通知它要更新哪个嵌套对象。

新的处理程序看起来像这样:

const handleInputChanges = level => e => {
  if (!level) {
    // Assume root level
    setCar({
      ...car,
      [e.target.name] : e.target.value
    })
  } else {
    setCar({
      ...car,
      [level]: {
        ...car[level],
        [e.target.name] : e.target.value
      }
    })
  }
};

然后像这样修改你的表单:

<InputText
  type="text"
  name="brand"
  placeholder="Brand"
  value={name}
  onChange={handleInputChanges()} // Root level
/>

<InputText
  type="text"
  name="address"
  placeholder="Address"
  value={location.address}
  onChange={handleInputChanges('location')} // location object
/>

<InputMask
  mask="(xxx)-xxx-xxxx"
  name="phone"
  placeholder="Phone Number"
  value={contact.phone}
  onChange={handleInputChanges('contact')} // contact object
/>

这只是每种类型的示例,您需要修改每个字段。