Javascript 将输入数据添加到deep object React.JS
我正在尝试根据用户输入创建对象。到现在为止,我一直在跟踪 它给了我以下错误: 未捕获的TypeError:无法读取未定义的属性“fullname”Javascript 将输入数据添加到deep object React.JS,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在尝试根据用户输入创建对象。到现在为止,我一直在跟踪 它给了我以下错误: 未捕获的TypeError:无法读取未定义的属性“fullname” const-App=()=>{ 设passengerObj={ “主要”:{ “全名”:“, “年龄”:空, }, “中学”:[], } const[passengerdata,setPassengerData]=useState(passengerObj) 返回( )}当您为全名或年龄输入一些数据时,代码中实际发生的情况整个状态对象被事件对象覆盖
const-App=()=>{
设passengerObj={
“主要”:{
“全名”:“,
“年龄”:空,
},
“中学”:[],
}
const[passengerdata,setPassengerData]=useState(passengerObj)
返回(
)}
当您为全名
或年龄
输入一些数据时,代码中实际发生的情况整个状态对象被事件对象覆盖。因此,对象将不会有任何名为primary
的属性,因此最终当您尝试访问fullname
时,会出现它的给定错误
请用以下代码更新您的代码。我添加了两种方法来更新状态中的fullname
和age
let passengerObj={
“主要”:{
“全名”:“,
“年龄”:空,
},
“中学”:[],
}
const[passengerdata,setPassengerData]=useState(passengerObj)
常数设置=(年龄)=>{
setPassengerData({
…乘客数据,
主要:{
…passengerdata.primary,
“年龄”:年龄
}
})
}
常量setFullname=(名称)=>{
setPassengerData({
…乘客数据,
主要:{
…passengerdata.primary,
“全名”:姓名
}
})
}
返回(
setFullname(e.target.value)}
必需的/>
设置(如target.value)}
必需的/>
)}
下面是另一个版本,它是用于更新任何输入字段的通用方法
let passengerObj={
“主要”:{
“全名”:“,
“年龄”:空,
},
“中学”:[],
}
const[passengerdata,setPassengerData]=使用状态(passengerObj);
const setFormData=(名称、值)=>{
设置passengerData(passengerData=>{
…乘客数据,
主要:{
…passengerData.primary,
[名称]:值,
}
})
}
返回(
setFormData(e.target.name,e.target.value)}
必需的/>
setFormData(e.target.name,e.target.value)}
必需的/>
)
希望这能有所帮助。问题在于
一旦更改
实现,它会接受事件
对象,您试图将事件设置为passengerData
但是在使用setState
时还有另一个问题,即不能获得过时状态
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}
/>
);
};
但是,在回调中使用e.target.event
会导致错误,因此您应该使用带有useRef
hook的引用:
此解决方案不会在每次渲染时重新创建onChange
(因为useCallback
和useState
的功能更新),也不会有任何过时状态
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}
/>
);
};
const passengerObj={
主要:{
全名:“”,
年龄:零
},
中学:[]
};
常量应用=()=>{
const[passengerdata,setPassengerData]=使用状态(passengerObj);
const inputRef=useRef();
const onChange=useCallback(()=>{
setPassengerData(上一页=>({
…上一页,
主要:{
…上一级,
全名:inputRef.current.value
}
}));
}, []);
返回(
);
};
这可能是HEPL
函数应用程序(){
设passengerObj={
“主要”:{
“全名”:“,
“年龄”:空,
},
“中学”:[],
};
const[passengerdata,setPassengerData]=React.useState(passengerObj);
返回(
{
const{value}=e.target;
setPassengerData((passengerdata)=>({
…乘客数据,
主要:{
…passengerdata.primary,
全名:value
}
}));
}}
必需的/>
{
}}
必需的/>
);
}
注意
const{value}=e.target代码>编写一个通用的onChangeHandler
,它的动态性足以更新多个输入元素
为您的输入提供一个名称。向处理程序提供类型(主/次)和事件
处理程序
consthandlechange=(e,type)=>{
常数{target}=e;
setPassengerData(上一页=>({
…上一页,
[输入]:{
…上一个[类型],
[target.name]:target.value
}
}));
};
JSX
handleChange(e,“primary”)}
name=“fullname”
必修的
/>
从onChange直接调用setPassengerData时,您期望得到什么?我建议使用基本调试-console.log(passengerData)。@jornsharpe我用粗体突出显示了我的期望。但您并没有试图这样做。您正在使用onChange的默认参数替换整个状态。再次进行一些基本调试,您将很快看到为什么passengerData.primary变得未定义。这与React或hooks无关,同样的事情也会发生在vanilla JS中,有一个常规赋值。e.target.value上有一个闭包,请检查您的答案,尝试键入一些内容。这很好,我看不出任何问题。我已经在问题中提供的沙箱中尝试了相同的代码,并按预期工作。你是对的,我的错,我认为它是setPassengerData(prev=>