开发者问题收集

将输入数据添加到深度对象 React.JS

2020-06-14
101

我正在尝试根据用户输入创建对象。到目前为止,我一直在遵循。

它给出了以下错误:

Uncaught TypeError: Cannot read property 'fullname' of undefined

const App = () => {

  let passengerObj = {
        "primary": {
            "fullname": "",
            "age": null,
        },
        "secondary": [],
    }
    
    const [passengerdata, setPassengerData] = useState(passengerObj)

        return (
            <form className="passenger-form">
                    <input 
                        type="text" 
                        placeholder="Full Name" 
                        value={passengerdata.primary.fullname}
                        onChange={setPassengerData}
                        required/>
                    <input 
                        type="number" 
                        placeholder="Age" 
                        value={passengerdata.primary.age || ""}
                        onChange={setPassengerData}
                        required/>
                  <div className="secondary-passenger-data">
                        <input 
                            type="text" 
                            placeholder="Full Name of Passenger2"
                            required/>
                        <input type="number"
                            placeholder="Age Passenger2"
                            required/>
                   </div>
                   <div className="secondary-passenger-data">
                        <input 
                            type="text" 
                            placeholder="Full Name of Passenger3"
                            required/>
                        <input type="number"
                            placeholder="Age Passenger3"
                            required/>
                   </div>
             </form>
  )}

当我尝试在passengerObj中添加主要和次要数据时。因此,我可以保存它。但是,它想允许我这样做。

不确定如何使用钩子将主要和次要数据添加到对象。

在这里,我在沙盒中重现了它。

https://codesandbox.io/s/distracted-sunset-89ecj?file=/src/App.js:0-1184

如有任何建议,我们将不胜感激。

3个回答

编写一个通用的 onChangeHandler ,该处理程序足够动态,可以更新多个输入元素。

为您的输入提供一个名称。为处理程序提供一个类型(主要/次要)和事件。

更新的工作演示

处理程序

const handleChange = (e, type) => {
    const { target } = e;
    setPassengerData(prev => ({
      ...prev,
      [type]: {
        ...prev[type],
        [target.name]: target.value
      }
    }));
  };

JSX

<input
        type="text"
        placeholder="Full Name"
        value={passengerdata.primary.fullname}
        onChange={e => handleChange(e, "primary")}
        name="fullname"
        required
      />
gdh
2020-06-14

当您输入 fullnameage 的一些数据时,代码中实际发生的情况是整个状态对象被事件对象覆盖。因此,该对象将没有任何名为 primary 的属性,因此最终当您尝试访问 fullname 时,会出现错误。

请使用以下代码更新您的代码。我添加了两种方法来更新状态中的 fullnameage

let passengerObj = {
  "primary": {
      "fullname": "",
      "age": null,
  },
  "secondary": [],
}

const [passengerdata, setPassengerData] = useState(passengerObj)

const setAge = (age) => {
  setPassengerData({
    ...passengerdata,
    primary: {
      ...passengerdata.primary,
      "age": age
    }
  })
}

const setFullname = (name) => {
  setPassengerData({
    ...passengerdata,
    primary: {
      ...passengerdata.primary,
      "fullname": name
    }
  })
}
  return (
      <form className="passenger-form">
              <input 
                  type="text" 
                  placeholder="Full Name" 
                  value={passengerdata.primary.fullname}
                  onChange={(e) => setFullname(e.target.value)}
                  required/>
              <input 
                  type="number" 
                  placeholder="Age" 
                  value={passengerdata.primary.age || ""}
                  onChange={(e) => setAge(e.target.value)}
                  required/>
            <div className="secondary-passenger-data">
                  <input 
                      type="text" 
                      placeholder="Full Name of Passenger2"
                      required/>
                  <input type="number"
                      placeholder="Age Passenger2"
                      required/>
             </div>
             <div className="secondary-passenger-data">
                  <input 
                      type="text" 
                      placeholder="Full Name of Passenger3"
                      required/>
                  <input type="number"
                      placeholder="Age Passenger3"
                      required/>
             </div>
       </form>
)}

这是另一个版本,它是用于更新任何输入字段的通用方法。

let passengerObj = {
  "primary": {
      "fullname": "",
      "age": null,
  },
  "secondary": [],
}

const [passengerdata, setPassengerData] = useState(passengerObj);

const setFormData = (name, value) => {
  setPassengerData(passengerData => {
    ...passengerData,
    primary: {
      ...passengerData.primary,
      [name]: value,
    }
  })
}

return (
      <form className="passenger-form">
              <input 
                  name="fullname"
                  type="text" 
                  placeholder="Full Name" 
                  value={passengerdata.primary.fullname}
                  onChange={(e) => setFormData(e.target.name, e.target.value)}
                  required/>
              <input 
                  name="age"
                  type="number" 
                  placeholder="Age" 
                  value={passengerdata.primary.age || ""}
                  onChange={(e) => setFormData(e.target.name, e.target.value)}
                  required/>
            <div className="secondary-passenger-data">
                  <input 
                      type="text" 
                      placeholder="Full Name of Passenger2"
                      required/>
                  <input type="number"
                      placeholder="Age Passenger2"
                      required/>
             </div>
             <div className="secondary-passenger-data">
                  <input 
                      type="text" 
                      placeholder="Full Name of Passenger3"
                      required/>
                  <input type="number"
                      placeholder="Age Passenger3"
                      required/>
             </div>
       </form>
)

希望这有帮助。

Nithish
2020-06-14

这也许有帮助

在此处输入图片描述

function App() {
  let passengerObj = {
    "primary": {
      "fullname": "",
      "age": null,
    },
    "secondary": [],
  };

  const [passengerdata, setPassengerData] = React.useState(passengerObj);

  return (
    <form className="passenger-form">
      <input
        type="text"
        placeholder="Full Name"
        value={passengerdata.primary.fullname}
        onChange={(e) => {
          const {value} = e.target;
          setPassengerData((passengerdata) => ({
            ...passengerdata,
            primary: {
              ...passengerdata.primary,
              fullname: value
            }
          }));
        }}
        required/>
      <input
        type="number"
        placeholder="Age"
        value={passengerdata.primary.age || ""}
        onChange={() => {

        }}
        required/>
      <div className="secondary-passenger-data">
        <input
          type="text"
          placeholder="Full Name of Passenger2"
          required/>
        <input type="number"
               placeholder="Age Passenger2"
               required/>
      </div>
      <div className="secondary-passenger-data">
        <input
          type="text"
          placeholder="Full Name of Passenger3"
          required/>
        <input type="number"
               placeholder="Age Passenger3"
               required/>
      </div>
    </form>
  );
}

注意 const {value} = e.target;

joshua
2020-06-14