亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

無法使用 fetch POST 方法對已卸載的組件執行 React 狀態更新

無法使用 fetch POST 方法對已卸載的組件執行 React 狀態更新

慕哥6287543 2024-01-18 16:10:53
當我使用 fetch post 方法時,我收到此警告,如何取消 useEffect 清理函數中的所有訂閱和異步任務。使用我的 Post 方法。警告:無法對已卸載的組件執行 React 狀態更新。這是一個空操作,但它表明應用程序中存在內存泄漏。要修復此問題,請取消 useEffect 清理函數中的所有訂閱和異步任務。import React from "react";import { useHistory } from "react-router-dom";import { UPLOAD_PRESET, CLOUD_NAME, SERVER_API } from "../../config";const uploadImage = async (file) => {  const url = `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`;  const formData = new FormData();  formData.append("file", file);  formData.append("upload_preset", UPLOAD_PRESET);  const res = await fetch(url, {    method: "POST",    body: formData,  });  if (!res.ok) {    throw new Error(`Can't upload image. ${res.status}`);  }  const data = await res.json();  return await data.eager[0].secure_url;};const createAlbum = async (data) => {  const res = await fetch(`${SERVER_API}/api/v1/albums`, {    method: "POST",    body: JSON.stringify(data),    headers: {      "Content-Type": "application/json",    },  });  if (!res.ok) {    throw new Error(`An error has occurred: ${res.status}`);  }  const json = await res.json();  return json.data._id;};const Form = ({ file, loading, setError, album, color, children }) => {  let history = useHistory();  const clearError = () => setError("");  const handleSubmit = async (e) => {    e.preventDefault();    clearError();    try {      if (!file) {        throw new Error("Please select a file to add.");      }      if (!album.trim("") || !color.trim()) {        throw new Error("Please enter all the field values.");      }      loading(true);      const fileUrl = await uploadImage(file);      const data = {        name: album,        bckImgUrl: fileUrl,        color: color,      };      const albumId = await createAlbum(data);      history.push(`/albums/${albumId}`);    } catch (error) {      setError(error.message);    } finally {      loading(false);    }  };  return <form onSubmit={handleSubmit}>{children}</form>;};export default Form;
查看完整描述

2 回答

?
青春有我

TA貢獻1784條經驗 獲得超8個贊

我想我應該展示如何將其提取到自定義掛鉤中。


function useHasUnmountedRef() {

? const hasUnmountedRef = useRef(false);

? useEffect(() => {

? ? return () => {

? ? ? hasUnmountedRef.current = true;

? ? }

? }, []);

? return hasUnmountedRef;

}


function Form() {


? const hasUnmountedRef = useHasUnmountedRef();


? const handleSubmit = async () => {


? ? await asyncStuff();


? ? if (hasUnmountedRef.current) {

? ? ? // escape early because component has unmounted

? ? ? return;

? ? }


? ? // Thanks to the guard clause above, you can guarantee at this

? ? // point that your component is still mounted. You can perform

? ? // state updates without generating a React warning.?

? ? //

? ? // If you do another "await" however, you will need to check

? ? // again. Everytime you await something async, there is a chance

? ? // that the component could have unmounted while waiting for the

? ? // async stuff to complete.


? };


? return (

? ? <form onSubmit={handleSubmit} />

? );

}


export default Form;


查看完整回答
反對 回復 2024-01-18
?
楊__羊羊

TA貢獻1943條經驗 獲得超7個贊

您可以React.useRef為此使用:


在您的組件中:


const hasUnmounted = React.useRef(false);


React.useEffect(() => {


 // maybe you have your side effects here, so you can use the boolean to avoid 

 // state updates when the component is unmounted


 if(!hasUnmounted.current) {

  // do state update 

 }

 return () => {

  hasUnmounted.current = true;

 }

}, [])

React.useRef適合解決這個問題,因為它與更改組件的狀態非常不同,這有點像類組件中的實例變量,更改它不會觸發重新渲染。


查看完整回答
反對 回復 2024-01-18
  • 2 回答
  • 0 關注
  • 156 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號