[英]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
(因為useCallback
和useState
的功能更新),也不會有任何陳舊的 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}
/>
);
};
這可能有助於
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.