我正在React中构建一个表单。我有一个添加按钮来复制一个窗体块,并有一个删除按钮来删除该窗体块。
当组件被渲染时,我添加了blockIds
,这就是问题所在:
当页面上有多个表单块实例时,例如
医生1
2号医生
3号医生
4号医生
并且我想删除Doctor 2,removeFormBlock
删除带有blockId=doctor_1
(零索引)的块,但是当doctorFormBlocks
重新呈现在表单上时,将生成并分配新的blockIds
,并且该匹配不匹配this.state.doctoFormBlocks
中有什么。
我应该如何处理这个问题,即。我应该在哪里生成blockId
?我在<DoctorFormBlock>
中尝试过,但是麻烦是将ID传递回appendFormBlock
和removeFormBlock
在<DoctorsForm>
中。
我还初始化了this.state. doctorFormBlocks
中的第一个块(从未删除)。不知道这是否正确。
class DoctorsForm extends React.Component {
constructor(props) {
super(props);
...
this.state = {
title,
form,
content,
doctorFormBlocks: ['doctor_0'],
};
...
}
appendFormBlock(e) {
const newBlock = `doctor_${this.state.doctorFormBlocks.length}`;
this.setState({
doctorFormBlocks: this.state.doctorFormBlocks.concat([newBlock]),
});
}
removeFormBlock(e) {
const blockToRemoveId = e.target.parentNode.parentNode.id;
this.setState(
{doctorFormBlocks: this.state.doctorFormBlocks.filter(block => block !== blockToRemoveId)},
);
}
render() {
return (
...
<div className="form__section">
<h2>{content.treatingDoctorsTitle}</h2>
<RichText content={HtmlEntity.decode(content.treatingDoctorsText)} />
{doctorFormBlocks.map((block, i) => (
<DoctorFormBlock
form={form}
key={i}
blockId={`doctor-${i}`}
id={i + 1}
handleRemove={this.removeFormBlock.bind(this)}
/>
))}
<AddRemoveButton typeToAdd="doctor" handleAppend={this.appendFormBlock.bind(this)} />
</div>
...
)
}
}
class DoctorFormBlock extends React.Component {
...
render() {
const {form, id, blockId, handleRemove} = this.props;
return (
<section className="form__block" id={blockId}>
{id > 1 && <AddRemoveButton isRemove handleRemove={handleRemove} />}
<h3>Doctor {id}</h3>
<LayoutField form={form} fieldId="doctorsSpeciality" sectionId="doctorDetailsForm" />
<LayoutField form={form} fieldId="name" sectionId="doctorDetailsForm" />
<LayoutField form={form} fieldId="address" sectionId="doctorDetailsForm" />
<LayoutField form={form} fieldId="contactNumber" sectionId="doctorDetailsForm" />
</section>
);
}
}
最佳答案
我相信问题出在这行代码上:
blockId={`doctor-${i}`}
这或多或少是“ doctor-” + currentIndex
由于您要遍历数组,因此您的ID将在行中(0、1、2、3、4等)。因此,当您删除1时,它会重新渲染。就像(0,1,2,3)。请注意缺少的4。
我相信您应该像下面这样使用
block
:blockId={block}
除了您最初遇到的问题外,还有一些很可能令人头疼的问题,我们现在应该清除掉,并消除其他代码错误。
e.target与e.currentTarget
小心
e.target
。 e.target
倾向于更改其所指元素。您可能需要e.currentTarget
。currentTarget
始终引用事件附加到的元素。有关更多信息,请参见documention。element.parentNode.parentNode.nightmare
关于
e.target.parentNode.parentNode.id;
。 parentNode.parentNode
是一场噩梦。如果要上升1 parentNode
好的...一旦开始多次上升,您将失去前进的方向。可以通过将id作为参数传递给
removeFormBlock
来避免这种情况。removeFormBlock(id) {
this.setState(
{doctorFormBlocks: this.state.doctorFormBlocks.filter(block => block !== id)},
);
}
//And in your JSX element
<AddRemoveButton isRemove handleRemove={() => { handleRemove(blockId) } } />
我们在这里所做的就是使AddRemoveButton的handleRemove引用匿名函数。然后,该匿名函数将调用
handleRemove
并传入blockId
。这样,我们就可以通过函数参数来访问blockId,而不是父节点的噩梦。
关于javascript - 为React组件分配ID以添加到状态并在render函数中映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48999791/