簡體   English   中英

將輸入數據添加到深度 object React.JS

[英]Add input data to deep object React.JS

我正在嘗試根據用戶輸入創建 object。 我一直關注到現在。

它給了我以下錯誤:

未捕獲的類型錯誤:無法讀取未定義的屬性“全名”

 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 中添加主要和次要數據時。 所以,我可以保存它。 但是,它想讓我這樣做。

不知道如何使用鈎子將主要和輔助數據添加到 Object。

這里沙箱我重現它。

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

任何將不勝感激。

編寫一個通用的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
      />

當您輸入一些fullname名數據或age整個 state object 被事件 object 覆蓋時,代碼中實際發生了什么。 因此,object 將沒有任何稱為primary的屬性,因此最終當您嘗試訪問fullname名時,它會給出錯誤。

請使用以下代碼更新您的代碼。 我添加了兩種方法來更新 state 中的fullname名和age

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>
)

希望這可以幫助。

問題在於onChange實現,它接受event object 並且您嘗試將事件設置為passengerData數據。

但是使用setState時還有另一個問題, 您想使用功能更新來避免過時的 state。

但是,在回調中使用e.target.event在這個 value 上有值閉包,所以你應該使用帶有useRef鈎子的引用:

此解決方案不會在每次渲染時重新創建onChange (因為useCallbackuseState的功能更新),也不會有任何陳舊的 state。

const passengerObj = {
  primary: {
    fullname: '',
    age: null
  },
  secondary: []
};

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

  const inputRef = useRef();

  const onChange = useCallback(() => {
    setPassengerData(prev => ({
      ...prev,
      primary: {
        ...prev.primary,
        fullname: inputRef.current.value
      }
    }));
  }, []);

  return (
    <input
      ref={inputRef}
      value={passengerdata.primary.fullname}
      onChange={onChange}
    />
  );
};

編輯美麗的sammet-mir70

這可能有助於

在此處輸入圖像描述

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM