Javascript 如何使用useState钩子更新现有的对象数组(向数组中添加新对象)?
我有一个onChange处理程序,可以用它编辑带有输入字段的某些对象 onChange处理程序如下所示:Javascript 如何使用useState钩子更新现有的对象数组(向数组中添加新对象)?,javascript,reactjs,typescript,react-redux,react-hooks,Javascript,Reactjs,Typescript,React Redux,React Hooks,我有一个onChange处理程序,可以用它编辑带有输入字段的某些对象 onChange处理程序如下所示: // First I get the current state const [persons, setPersons] = useState(service.persons); <InputWrapper> <TextField type="text" label="Person name"
// First I get the current state
const [persons, setPersons] = useState(service.persons);
<InputWrapper>
<TextField
type="text"
label="Person name"
name="person_name"
value=' '
onChange={e => setNewPerson({ ...newPerson, [e.target.name]: e.target.value })}
/>
</InputWrapper>
API为人员(对象数组)返回以下内容:
我的onChange处理程序如下所示(…用于编辑给定人员的if语句的第一部分工作正常,但用于创建新人员的else语句工作不正常):
我的模板如下所示(仅空输入字段,用于创建具有person\u公司和person\u姓名的新人员):
但我的目标是,当我创建一个新的人时,对象应该按如下方式更新:
contacts (3) [{…}, {…}, {…}]
0: {person_company: "Google", person_name: "John Doe"}
1: {person_company: "Facebook", person_name: "Jane Doe"}
2: {person_company: "Amazon", person_name: "Max Mustermann"}
我做错了什么?试试看,不要在对象内部展开列表,而是展开列表并添加对象,这也是因为当你打电话给一个新人时,没有提供索引:
const updatePersons = (e: any, index?: number) => {
if (index !== undefined) {
const updatedPersons = [...persons];
updatedPersons[index][e.target.name] = e.target.value;
setPersons(updatedPersons.map((person)=>({...person,new:false})));
} else {
const lastPerson = persons.slice(-1)[0];
if (lastPerson.new){
setPersons([...persons.slice(0,-1), {...lastPerson ,[e.target.name]:e.target.value}]);
} else {
setPersons([...persons,{[e.target.name]:e.target.value , new:true}]
}
}
};
不幸的是,我无法使用建议的方法解决它。但我用了另一种方式 我修改了updatePersons方法,它现在只处理带有ID的案例(因此不再有其他块) 相反,我现在直接在textfields的onChange处理程序中创建一个新人
// I created another useState hook for the new Person
// ..and provided an initial state (empty strings) by instantiating a new Person:
const [newPerson, setNewPerson] = useState(new Person());
我的文本字段现在如下所示:
// First I get the current state
const [persons, setPersons] = useState(service.persons);
<InputWrapper>
<TextField
type="text"
label="Person name"
name="person_name"
value=' '
onChange={e => setNewPerson({ ...newPerson, [e.target.name]: e.target.value })}
/>
</InputWrapper>
让我知道这个解决方案是否还可以。使用这种方法,每次击键都会添加一个新对象,在person_company输入字段中键入“test”后,我得到以下结果(并且输入字段中的值仍然没有更新):在调用
onChange={e=>updatePersons(e)}时,还需要提供索引
soonChange={e=>updatePersons(e,index)}
,或者您需要考虑其他方法来保持“新人”索引,即使在增加列表大小后仍然保持不变,请给它一个快照。如果进展顺利,请通知我。。。很好,幸运的是,这种方法不起作用。但我的解决方法不同——我采用了updatePersons方法,它现在只处理带有ID的案例(因此不再有其他块)。相反,我现在直接在textfields的onChange处理程序中创建一个新人。我还创建了一个submitHandler,在其中更新状态并随后清空表单字段。我将把这个方法作为一个答案。让我知道这个解决方案是否也可以接受。你告诉我们它是否有效……是的,它有效:)。
const updatePersons = (e: any, index?: number) => {
e.preventDefault(); // is this needed here?
if (index !== undefined) {
const updatedPersons = [...persons];
updatedPersons[index][e.target.name] = e.target.value;
setPersons(updatedPersons);
}
};
// I created another useState hook for the new Person
// ..and provided an initial state (empty strings) by instantiating a new Person:
const [newPerson, setNewPerson] = useState(new Person());
<InputWrapper>
<TextField
type="text"
label="Person name"
name="person_name"
value=' '
onChange={e => setNewPerson({ ...newPerson, [e.target.name]: e.target.value })}
/>
</InputWrapper>
const submitHandler = (e: any) => {
e.preventDefault(); // is this needed here?
setPersons([...persons, newPerson]);
setNewPerson(new Person()); // Empty the form fields
};