Reactjs React TypeScript:如何将多个文件设置为状态?
我面临着一个问题,可能是一个非常简单的问题,但我从几个小时以来就被困在这里,所以我想请你帮忙 我有一个简单的文件输入,我想将此文件设置为状态,以便稍后提交表单时上载文件Reactjs React TypeScript:如何将多个文件设置为状态?,reactjs,typescript,react-hooks,typescript-typings,Reactjs,Typescript,React Hooks,Typescript Typings,我面临着一个问题,可能是一个非常简单的问题,但我从几个小时以来就被困在这里,所以我想请你帮忙 我有一个简单的文件输入,我想将此文件设置为状态,以便稍后提交表单时上载文件 const [inputTattoos, setInputTattoos] = useState<[{}]>(); const handleImageChange = async ({ currentTarget: input, }: React.ChangeEvent<HTMLInputElem
const [inputTattoos, setInputTattoos] = useState<[{}]>();
const handleImageChange = async ({
currentTarget: input,
}: React.ChangeEvent<HTMLInputElement>) => {
if (input.files === null) return;
console.log(input.files);
setInputTattoos([{ ...input.files }]);
const[InputAttoos,setInputAttoos]=useState();
常量handleImageChange=async({
当前目标:输入,
}:React.ChangeEvent)=>{
if(input.files==null)返回;
console.log(input.files);
setInputAttoos([{…input.files}]);
使用此代码,我可以将文件写入状态,但这不是我希望在状态中存储文件的方式,因为我的状态如下所示:
我有一个数组,里面有一个对象。实际上,我从input.files得到的只是一个对象数组,但我无法像在控制台上那样存储这个input.files。我尝试了很多解决方案,但这是唯一有效的方法。对于其他解决方案,我总是得到一个空对象或一个文件列表(未定义)例如,在使用此解决方案的状态下:
const [inputTattoos, setInputTattoos] = useState<FileList>()
const handleImageChange = async ({
currentTarget: input,
}: React.ChangeEvent<HTMLInputElement>) => {
if (input.files === null) return;
console.log(input.files);
setInputTattoos(input.files);
const[InputAttoos,SetInputAttoos]=useState()
常量handleImageChange=async({
当前目标:输入,
}:React.ChangeEvent)=>{
if(input.files==null)返回;
console.log(input.files);
setInputAttoos(input.files);
这里怎么了?谢谢!我只存储文件对象,没有对象包装或任何东西:
const [inputTattoos, setInputTattoos] = useState<File[]>([]);
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^−−^^
const handleImageChange = ({
currentTarget: {files},
}: React.ChangeEvent<HTMLInputElement>) => {
if (files && files.length) {
setInputTattoos(existing => [...existing, ...files]);
// −−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
// ...
}
其中的更改是回调:
existing => existing.concat(Array.from(files))
请注意,由于文件
是一个文件列表
,而不是一个数组,因此我们需要将其转换为concat
的数组以正确处理它
Array.from
仅使用了几年,但很容易进行多重填充;如果您不想这样做,这里有一个替代方法,它不使用任何现代功能(箭头功能除外):
下面是使用数组的完整示例。对于该部分,请参见
:
const{useState}=React;
函数示例(){
常量[InputAttoos,SetInputAttoos]=useState/**/([]);
常量[inputKey,setInputKey]=useState(0);
常量handleImageChange=({
当前目标:{file},
}/*:React.ChangeEvent*/)=>{
if(files&&files.length){
setInputAttoos(existing=>existing.concat(Array.from(files));
}
//通过强制新输入重置输入
setInputKey(key=>key+1);
}
返回(
所选纹身({inputtatoos.length}):
{inputAttoos.map((文件,索引)=>
- {file.name}
)}
加:
);
}
ReactDOM.render(,document.getElementById(“根”);
“…但这不是我想在状态下存储它的方式…”您想如何存储它?我想像在控制台.log(input.files)上一样存储它。我有一个数组“FileList”,其中包含每个文件的对象[文件对象]。但我现在要存储的是一个数组,其中包含一个对象每个文件的对象[{File objects}].好的,很好,这是我在写我的答案时假设的。:-)谢谢!但是我如何才能将当前状态传递给回调?我得到“它未定义”@wyndham007-您不需要将当前状态传递给回调函数,React会传递。React状态设置器就是这样工作的,您可以直接传递数据,也可以传递函数,它们将使用当前信息调用。如果您已将useState
更新为如上所示的状态,则当前状态不会是未定义的
(它是未定义的
,因为您的原始代码没有将任何内容传递到useState
)我也修复了上面提到的concat
问题。@wyndham007-我用一个完整的示例更新了答案,这样您就可以看到它的实际操作(特定于TypeScript的部分被注释掉了)。非常感谢您的示例!!现在typescript编译器说:“FileList | null”类型的参数不可分配给“ArrayLike”类型的参数。“null”类型不可分配给“ArrayLike”@wyndham007-文件对象存储在状态,它们不仅仅是{}
,从显示文件名称的实时示例中可以看出。至于Blob是什么,MDN是您的朋友:对象是对象的子类。请注意,如果要将这些对象存储在状态中,然后提交它们,则需要在构建表单提交时使用,因为它可以读取文件。
existing => existing.concat(Array.from(files))
existing => existing.concat(Array.prototype.slice.call(files))