Javascript 在渲染函数中为要添加到状态和映射的组件指定ID
我正在用React创建一个表单。我有一个添加按钮来复制一个表单块,还有一个删除按钮来删除该表单块 我在渲染组件时添加了Javascript 在渲染函数中为要添加到状态和映射的组件指定ID,javascript,reactjs,state,Javascript,Reactjs,State,我正在用React创建一个表单。我有一个添加按钮来复制一个表单块,还有一个删除按钮来删除该表单块 我在渲染组件时添加了blockid,这就是问题所在: 当页面上有多个表单块实例时,例如 医生1 医生2 医生3 医生4 我想删除Doctor 2,removeFormBlock删除带有blockId=Doctor_1(零索引)的块,但是当doctorFormBlocks在表单上重新呈现时,会生成和分配新的blockId,与此.state.doctorFormBlocks中的内容不匹配 我应该如何处理
blockid
,这就是问题所在:
当页面上有多个表单块实例时,例如
医生1
医生2
医生3
医生4
我想删除Doctor 2,removeFormBlock
删除带有blockId=Doctor_1
(零索引)的块,但是当doctorFormBlocks
在表单上重新呈现时,会生成和分配新的blockId
,与此.state.doctorFormBlocks
中的内容不匹配
我应该如何处理这个问题,即我应该在哪里生成blockId
s?我尝试了
,但问题是将id返回到
中的appendFormBlock
和removeFormBlock
我还初始化了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>
);
}
}
类DoctorsForm扩展了React.Component{
建造师(道具){
超级(道具);
...
此.state={
标题
形式,
内容,,
doctorFormBlocks:['doctor_0'],
};
...
}
附录模块(e){
const newBlock=`doctor_${this.state.doctorFormBlocks.length}`;
这是我的国家({
doctorFormBlocks:this.state.doctorFormBlocks.concat([newBlock]),
});
}
移除模板块(e){
const blockToRemoveId=e.target.parentNode.parentNode.id;
这是我的国家(
{doctorFormBlocks:this.state.doctorFormBlocks.filter(block=>block!==blockToRemoveId)},
);
}
render(){
返回(
...
{content.treatingdoctorsttitle}
{doctorFormBlocks.map((块,i)=>(
))}
...
)
}
}
类DoctorFormBlock扩展了React.Component{
...
render(){
const{form,id,blockId,handleRemove}=this.props;
返回(
{id>1&&}
医生{id}
);
}
}
我认为问题出在这一行代码上:
blockId={`doctor-${i}`}
这或多或少是“医生-”+当前索引
由于您在一个数组中循环,所以您的ID将在第(0、1、2、3、4等)行中。因此,当删除1时,它将重新渲染。它就像(0,1,2,3)。注意缺少的4
我认为您应该像下面这样使用block
:
blockId={block}
除了您最初的问题之外,我们现在应该清理一些非常可能令人头痛的问题和其他代码气味
e、 目标与当前目标 小心
e.target
<代码>e.目标有改变其所指元素的倾向。您可能需要e.currentTarget
currentTarget
始终指事件附加到的元素。有关更多信息,请参阅
element.parentNode.parentNode.Demo梦 关于
e.target.parentNode.parentNode.id代码>。那是一场噩梦。如果你想上升1parentNode
好的。。。一旦你开始多次上升,你就失去了方向的轨道
这可以通过将id作为参数传递给removeFormBlock
来避免
removeFormBlock(id) {
this.setState(
{doctorFormBlocks: this.state.doctorFormBlocks.filter(block => block !== id)},
);
}
//And in your JSX element
<AddRemoveButton isRemove handleRemove={() => { handleRemove(blockId) } } />
removeFormBlock(id){
这是我的国家(
{doctorFormBlocks:this.state.doctorFormBlocks.filter(block=>block!==id)},
);
}
//在JSX元素中
{handleRemove(blockId)}}/>
我们在这里做的是使AddRemoveButton的handleRemove引用一个匿名函数。然后,该匿名函数将调用handleRemove
并传入blockId
。
这样,我们就可以通过函数参数而不是parentNodes的噩梦来访问blockId。我相信问题出在这行代码上:
blockId={`doctor-${i}`}
这或多或少是“医生-”+当前索引
由于您在一个数组中循环,所以您的ID将在第(0、1、2、3、4等)行中。因此,当删除1时,它将重新渲染。它就像(0,1,2,3)。注意缺少的4
我认为您应该像下面这样使用block
:
blockId={block}
除了您最初的问题之外,我们现在应该清理一些非常可能令人头痛的问题和其他代码气味
e、 目标与当前目标
小心e.target
<代码>e.目标
有改变其所指元素的倾向。您可能需要e.currentTarget
currentTarget
始终指事件附加到的元素。有关更多信息,请参阅
element.parentNode.parentNode.Demo梦 关于
e.target.parentNode.parentNode.id代码>。那是一场噩梦。如果你想上升1parentNode
好的。。。一旦你开始多次上升,你就失去了方向的轨道
这可以通过将id作为参数传递给removeFormBlock
来避免
removeFormBlock(id) {
this.setState(
{doctorFormBlocks: this.state.doctorFormBlocks.filter(block => block !== id)},
);
}
//And in your JSX element
<AddRemoveButton isRemove handleRemove={() => { handleRemove(blockId) } } />
removeFormBlock(id){
这是我的国家(
{doctorFormBlocks:this.state.doctorFormBlocks.filter(block=>block!==id)},
);
}
//在JSX元素中
{handleRemove(blockId)}}/>
我们在这里做的是使AddRemoveButton的handleRemove引用一个匿名函数。然后,该匿名函数将调用handleRemove
并传入blockId
。
这样我们就可以通过函数参数而不是parentNodes的噩梦来访问blockId。