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

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

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

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

并且我想删除Doctor 2,removeFormBlock删除带有blockId=doctor_1(零索引)的块,但是当doctorFormBlocks重新呈现在表单上时,将生成并分配新的blockIds,并且该匹配不匹配this.state.doctoFormBlocks中有什么。

我应该如何处理这个问题,即。我应该在哪里生成blockId?我在<DoctorFormBlock>中尝试过,但是麻烦是将ID传递回appendFormBlockremoveFormBlock<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.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 - 为React组件分配ID以添加到状态并在render函数中映射,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48999791/

10-13 01:35