簡體   English   中英

如何在useEffect中得到一個Promise的結果

[英]How to get the result of a Promise in useEffect

具有以下代碼片段:

  useEffect(() => {
    if (uploadedFile) {
      const uploadedFileText = uploadedFile[0].text().then((a) => {
        return a;
      });

      const parsed = JSON.parse(uploadedFileText);
      setParsedFile(parsed);
    }
  }, [uploadedFile]);

上傳文件的類型: FileList | File[] FileList | File[] ,這是在字段中上傳的文件。 在我的例子中,它是一個 JSON 文件,但對於代碼中的其他一些方法,它需要作為二進制文件上傳。

在這個 useEffect 中,它應該被解析為 JSON 文件。

上面的代碼表示JSON.parse(...)上存在錯誤:

“Promise”類型的參數不可分配給“string”類型的參數。

它建議作為在JSON.parse中添加await的快速修復: const parsed = JSON.parse(await uploadedFileText);

但這肯定行不通,因為 useEffect 不是異步的,也無法向其添加異步。

如何解決這個問題?

useEffect 回調不能是異步的,但您可以在其主體中添加一個異步 function。

    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]);

或者您可以通過其他方式僅為邏輯創建單獨的函數。 您不需要將所有代碼都包含在 useEffect function 中。

       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]);

與其他人的答案略有不同,因為我不知道你為什么堅持要返回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]);

實際上,您可以通過創建異步的內部 function 來繞過 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]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM