gpt4 book ai didi

javascript - 将 ID 分配给 React 组件以添加到状态并在渲染函数中进行映射

转载 作者:行者123 更新时间:2023-12-03 02:24:43 25 4
gpt4 key购买 nike

我正在 React 中构建一个表单。我有一个添加按钮来复制表单 block ,还有一个删除按钮来删除该表单 block 。

我已添加blockIds当组件被渲染时,这就是问题所在:

当页面上有多个表单 block 实例时,例如。

医生1医生2医生3医生4

我想删除 Doctor 2,removeFormBlock删除带有 blockId=doctor_1 的 block (零索引),但是当 doctorFormBlocks在表单上重新呈现,新的 blockIds正在生成和分配,但与 this.state.doctoFormBlocks 中的内容不匹配.

我应该如何解决这个问题,即。我应该在哪里生成 blockId是?我试过<DoctorFormBlock>但麻烦在于将 id 传递回 appendFormBlockremoveFormBlock<DoctorsForm> .

我还初始化了 this.state. doctorFormBlocks 中的第一个 block (从未删除) 。也不确定这是否正确。

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.targete.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 - 将 ID 分配给 React 组件以添加到状态并在渲染函数中进行映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48999791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com