具有以下代码片段:
useEffect(() => {
if (uploadedFile) {
const uploadedFileText = uploadedFile[0].text().then((a) => {
return a;
});
const parsed = JSON.parse(uploadedFileText);
setParsedFile(parsed);
}
}, [uploadedFile]);
uploadedFile的类型:FileList | File[]
,是在字段中上传的文件。在我的例子中,它是一个JSON文件,但对于代码中的其他一些方法,它需要作为二进制文件上传。
在这个useEffect中,它应该被解析为JSON文件。
上面的代码表示JSON.parse(...)
:上有一个错误
类型为"Promise"的参数不可分配给类型为"string"的参数
建议在JSON.parse
:const parsed = JSON.parse(await uploadedFileText);
中添加await
作为快速解决方案
但这肯定不起作用,因为useEffect不是异步的,不能添加异步
如何解决此问题?
useEffect回调不能是异步的,但您可以在其主体中添加异步函数。
useEffect(() => {
async function parseFile() {
if (uploadedFile) {
const uploadedFileText = await uploadedFile[0].text().then((a) => {
return a;
});
const parsed = JSON.parse(uploadedFileText);
setParsedFile(parsed);
}
}
parseFile();
}, [uploadedFile]);
答案与其他答案略有不同,因为我不知道你为什么坚持返回uploadedFile
:的值
useEffect(() => {
// note: your condition was also potentially wrong
if (uploadedFile?.length) {
uploadedFile[0].text().then(uploadedFileText => {
const parsed = JSON.parse(uploadedFileText);
setParsedFile(parsed);
}).catch(err => {
// TODO : proper error management, file could not be parsed
});
}
}, [uploadedFile]);
或者您可以用其他方式只为逻辑创建seprate函数。您不需要在useEffect函数中包含所有代码。
const parseFile = useCallback(async () => {
const uploadedFileText = await uploadedFile[0].text().then((a) => {
return a;
});
const parsed = JSON.parse(uploadedFileText);
setParsedFile(parsed);
}, []);
useEffect(() => {
if (uploadedFile) {
parseFile();
}
}, [uploadedFile]);
您实际上可以通过创建一个内部函数Async:来绕过useEffect Async/Await约束
useEffect(() => {
const uploadFile = async() => { // <- Your new Async Function
if (uploadedFile) {
const uploadedFileText = await uploadedFile[0].text();
const parsed = JSON.parse(uploadedFileText);
setParsedFile(parsed);
}
}
uploadFile(); // <- Then you just call it at the bottom of the useEffect
}, [uploadedFile]);