我有一个 onChange 处理程序,我可以使用它来编辑具有输入字段的某些对象。
onChange 处理程序如下所示:
// First I get the current state
const [persons, setPersons] = useState(service.persons);
API 为人员(对象数组)返回以下内容:
contacts (2) [{…}, {…}]
0: {person_company: "Google", person_name: "John Doe"}
1: {person_company: "Facebook", person_name: "Jane Doe"}
我的 onChange 处理程序看起来像这样(..用于编辑给定人员的 if 语句的第一部分工作正常,但用于创建新人员的 else 语句没有):
const updatePersons = (e: any, index?: number) => {
if (index !== undefined) {
const updatedPersons = [...persons];
updatedPersons[index][e.target.name] = e.target.value;
setPersons(updatedPersons);
} else {
setPersons({ ...persons, [e.target.name]: e.target.value });
}
};
我的模板看起来像这样(只是用于创建具有 person_company 和 person_name 的新人员的空白输入字段):
<InputContainer>
<p>New person</p>
<InputWrapper>
<TextField
type="text"
label="Person company"
name='person_company'
value=' '
onChange={e => updatePersons(e)}
/>
</InputWrapper>
<InputWrapper>
<TextField
type="text"
label="Person name"
name="person_name"
value=' '
onChange={e => updatePersons(e)}
/>
</InputWrapper>
</InputContainer>
不幸的是,它不能那样工作。
第一个输入框只实现第一个字母,之后整个组件消失
如果我操纵它以使组件不消失,则输入字段的值不会更新(这可能是因为我设置了 value = ' '。我不知道我还应该提供什么)。
如果我在 1. 中提到的第一个字母之后控制台记录人员,则对象数组更新如下:
contacts {0: {…}, 1: {…}, company_name: " t"}
0: {person_company: "Google", person_name: "John Doe"}
1: {person_company: "Facebook", person_name: "Jane Doe"}
person_company: " t"
但我的目标是当我创建一个新人时,对象应该更新如下:
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"}
我在这里做错了什么?
答案 0 :(得分:2)
尝试不要在对象内部传播列表,而是传播列表并添加对象,这也是因为当您呼叫新人时没有提供索引:
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}]
}
}
};
答案 1 :(得分:0)
不幸的是,我无法使用建议的方法解决它。但我以不同的方式做到了。
我调整了 updatePersons 方法,该方法现在只处理带有 ID 的案例(因此不再有 else 块)。
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);
}
};
相反,我现在直接在文本字段的 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());
我的文本字段现在看起来像这样:
<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
};
让我知道这个解决方案是否也可以。