Javascript React中N号文件输入的添加和删除
我正在构建一个允许用户上传N个数据文件的东西。为了实现这一点,我添加了一个按钮,它将创建一个额外的文件上传选项。这是通过渲染函数中的一个简单for循环来完成的(有一个选择选项,只有在满足某些条件时才会出现,即“mergeColumnSelection”变量,您可以忽略它,但我会将其包括在内,以防它以某种方式结束相关): 如您所见,这将获取所选输入的索引,然后从生成for循环的数组中拼接它。从阵列拼接适当的文件,并且文件输入的数量正确。但是,显示的文件名存在问题。图片将有助于: 在这里,您可以看到一个示例,其中有人正准备上载三个 文件、健康、群集和星巴克 现在,我选择从列表中删除集群项目(项目2)。它是 在状态下从文件列表中删除,只保留运行状况和 星巴克。然而,for循环只是运行了两次,然后下降 最后一项-表示运行状况和群集 剩下的两个文件,即使实际上是健康的 还有星巴克 我曾考虑过将JSX块本身移动到状态,这样我就可以专门针对我想要删除的JSX输入元素——但这种方法的成功率有限,并且读到将JSX置于状态是不可取的。React实际上没有内置的方法来轻松删除特定的输入,并且我无法在文件输入中设置默认值,因此我无法轻松地将各个输入与状态中的对应输入绑定 我觉得这应该是一个很简单的问题,我被卡住了。感谢您的帮助 您是否尝试过以下方法:Javascript React中N号文件输入的添加和删除,javascript,reactjs,Javascript,Reactjs,我正在构建一个允许用户上传N个数据文件的东西。为了实现这一点,我添加了一个按钮,它将创建一个额外的文件上传选项。这是通过渲染函数中的一个简单for循环来完成的(有一个选择选项,只有在满足某些条件时才会出现,即“mergeColumnSelection”变量,您可以忽略它,但我会将其包括在内,以防它以某种方式结束相关): 如您所见,这将获取所选输入的索引,然后从生成for循环的数组中拼接它。从阵列拼接适当的文件,并且文件输入的数量正确。但是,显示的文件名存在问题。图片将有助于: 在这里,您可以看
{this.removeEnrichmentData(index)}}
这是一个可行的方法。您尝试过以下方法吗:
{this.removeEnrichmentData(index)}}
这是一个有效的例子。如果没有一个完全有效的例子,很难确定,但这与一个“有效”的例子非常相似,即当你不给元素数组一个关键道具时,React是如何出错的。你没有收到来自React的警告吗?尝试为要推送到数组的div指定一个key prop,当删除某个元素时,该属性对于现有元素不会改变(因此key={i}不起作用) 例如,如果正在渲染
<input type="file" key={1} />
<input type="file" key={2} />
<input type="file" key={3} />
<input type="file" key={4} />
当您删除键为{2}的时,它应该是
<input type="file" key={1} />
<input type="file" key={3} />
<input type="file" key={4} />
某种类型的递增id(如关系数据库中的id)或生成的唯一id就可以做到这一点。如果没有一个完全有效的示例,很难确定,但这非常类似于一个“有效”的示例,当您不给元素数组一个关键道具时,React是如何出错的。你没有收到来自React的警告吗?尝试为要推送到数组的div指定一个key prop,当删除某个元素时,该属性对于现有元素不会改变(因此key={i}不起作用) 例如,如果正在渲染
<input type="file" key={1} />
<input type="file" key={2} />
<input type="file" key={3} />
<input type="file" key={4} />
当您删除键为{2}的时,它应该是
<input type="file" key={1} />
<input type="file" key={3} />
<input type="file" key={4} />
某种递增的id(如关系数据库中的id)或生成的唯一id就可以实现这一点。@MilošRašić是正确的-您最初的问题是,您可能对输入的键使用数组索引。因此,如果您有10个编号为0…9的输入,并且您删除了索引为5的输入,那么您仍然在呈现键为0…8的项目,并且认为最后一个项目已被删除 根据您关于使用UUID的评论,听起来像是在
render()
方法本身中生成唯一的ID不要那样做从不在render()
中为关键帧生成随机值。当您这样做时,您每次都会告诉React“此项目与上次渲染的项目不同,请在此处销毁现有项目并替换为新项目”
相反,您应该在向状态中添加新条目时生成这些唯一ID。例如:
class FileInputList extends Component {
state = { inputs : [] }
addNewFileInput = () => {
const inputID = uuid();
const newInputs = this.state.inputs.concat({id : inputID});
this.setState({inputs : newInputs});
}
render() {
const {inputs} = this.state;
const inputList = inputs.map(inputEntry) => {
return <input type="file" key={inputEntry.id} />
});
return inputList;
}
}
类文件输入列表扩展组件{
状态={输入:[]}
addNewFileInput=()=>{
常量inputID=uuid();
const newInputs=this.state.inputs.concat({id:inputID});
this.setState({inputs:newInputs});
}
render(){
const{inputs}=this.state;
常量inputList=inputs.map(inpuntry)=>{
返回
});
返回输入列表;
}
}
@MilošRašić是正确的-您最初的问题是您可能对输入的键使用数组索引。因此,如果您有10个编号为0…9的输入,并且您删除了索引为5的输入,那么您仍然在呈现键为0…8的项目,并且认为最后一个项目已被删除
根据您关于使用UUID的评论,听起来像是在render()
方法本身中生成唯一的ID不要那样做从不在render()
中为关键帧生成随机值。当您这样做时,您每次都会告诉React“此项目与上次渲染的项目不同,请在此处销毁现有项目并替换为新项目”
相反,您应该在向状态中添加新条目时生成这些唯一ID。例如:
class FileInputList extends Component {
state = { inputs : [] }
addNewFileInput = () => {
const inputID = uuid();
const newInputs = this.state.inputs.concat({id : inputID});
this.setState({inputs : newInputs});
}
render() {
const {inputs} = this.state;
const inputList = inputs.map(inputEntry) => {
return <input type="file" key={inputEntry.id} />
});
return inputList;
}
}
类文件输入列表扩展组件{
状态={输入:[]}
addNewFileInput=()=>{
常量inputID=uuid();
const newInputs=this.state.inputs.concat({id:inputID});
this.setState({inputs:newInputs});
}
render(){
const{inputs}=this.state;
常量inputList=inputs.map(inpuntry)=>{
返回
});
返回输入列表;
}
}
你确定你的i
索引是正确的吗?是的,我想是的!您可以看到,我从for循环中传递'I'作为删除的索引参数。它总是从存储中拼接正确的内容,但是当它循环通过并重新渲染时,它总是剪掉最后渲染的项目,ins