问题的一些背景:我有一个动态输入字段表单,用户可以在其中通过从下拉菜单中选择一个选项来选择他们所属的社交媒体平台。还有一个相应的文本输入,用户可以在其中输入该社交媒体平台的用户名。用户可以按照相同的格式添加或删除输入字段。在以下屏幕截图中,窗体在 UI 上如下所示:
social_media_form_before_deleted_input_field
下面是它的 JSX 代码:
{socialMediaInputs.map((input, index) =>
<>
<tr className="socialMediaOptionsRow">
<td>
{index === 0 ? null :
<button onClick={event => handleDelete(event, input.id)}>Delete</button>
}
</td>
<td >
<select
id="socialMediaOptions"
onChange={event => handleSocialMediaOptions(event, setIsTextInputDisabled)}
required
name={input.id}
>
<option>choose</option>
<option name="socialMedia" value={"Twitter"}>Twitter</option>
<option name="socialMedia" value={"Facebook"}>Facebook</option>
<option name="socialMedia" value={"LinkedIn"}>LinkedIn</option>
<option name="socialMedia" value={"Instagram"}>Instagram</option>
<option name="socialMedia" value={"Medium"}>Medium</option>
<option name="socialMedia" value={"Other"}>Other</option>
</select>
</td>
<td>
<input
type="text"
onChange={handleAccountNameInput}
name={input.id}
disabled={isTextInputDisabled}
required
/>
</td>
</tr>
<tr>
<button
onClick={handleAddBtnClick}
disabled={socialMediaInputs.length >= 5}
>
<CgMathPlus/>
Add
</button>
</tr>
</>
问题是每当我通过按删除按钮删除输入字段时,输入字段确实会从socialMediaInputs
中删除 - 一个状态值,其中存储了输入字段的所有值并映射到 UI,如屏幕截图和代码所示 - 但它仍然出现在 UI 上。因此,根据上面的屏幕截图,如果我按下具有LinkedIn
的选择选项输入字段的删除按钮,则在UI上删除的不是该输入字段,而是始终是最后一个输入字段 - 在这种情况下,选择了Instagram
的选项输入字段。以下是该结果的屏幕截图:
social_media_form_after_deleted_input_field
正如您在第二个屏幕截图中看到的,包含company: LinkedIn
的对象确实会从socialMediaInputs
中删除,但它仍显示在 UI 上。当用户单击相应的"删除"按钮时,如何从 UI 中删除要删除的输入字段?
下面是处理被按下的删除按钮的javacript代码:
const handleDelete = (event, id_) => {
event.preventDefault();
const inputs_ = socialMediaInputs.filter(input => input.id !== id_);
setSocialMediaInputs(inputs_);
}
编辑:
当我向每个 tr 添加一个键时,按下删除按钮时,特定的 tr 确实会被删除,但已删除的行下方的任何行都会在 UI 上重置。因此,如果我删除选择了Facebook
的行,在下面的第一个屏幕截图中,它确实被删除了。但是它下面的行被重置 - 这是我不想要的 - 这在下面的第二个屏幕截图中看到。
form_with_key_before_deletion
form_with_key_after_deletion
问题是您忘记了映射数组并在 UI 中呈现相同的属性key
属性。如果没有key
,影子 dom 会混淆到数组中的项目被更改了。