簡體   English   中英

在反應中使用效果清理 function

[英]useEffect cleanup function in react

我收到此警告“無法在未安裝的組件上執行 React state 更新。 這是一個無操作,但它表明您的應用程序中存在 memory 泄漏。 要修復,請取消 useEffect 清理 function 中的所有訂閱和異步任務。

代碼

 const [photo, setPhoto] = useState([]);
 useEffect(() => {
 fetch('/mypost', {
  headers: {
    cookie: 'access_token',
  },
})
  .then((res) => res.json())
  .then((data) => {
    setPhoto(data.mypost);
  });
}, []);

數據已獲取,但我不知道要在清理中添加什么。 有什么建議么?

問題

問題是獲取請求已解決,但組件已卸載(出於某種原因),因此現在無法進行 state 更新。

解決方案

您需要使用Abort Controller來取消進行中的請求。 如果組件卸載,效果清理 function 會取消獲取請求。

useEffect(() => {
  const controller = new AbortController(); // <-- create controller
  const { signal } = controller; // <-- get signal for request

  fetch('/mypost', {
    headers: {
      cookie: 'access_token',
    },
    signal, // <-- pass signal with options
  })
    .then((res) => res.json())
    .then((data) => {
      setPhoto(data.mypost);
    });

  return () => controller.abort(); // <-- return cleanup function to abort
}, []);

注意:abort()被調用時, fetch() promise 以AbortError拒絕。

您可能需要在某處發現此 promise 拒絕。 您可以將 append 一個.catch塊添加到 Promise 鏈中。

  fetch('/mypost', {
    headers: {
      cookie: 'access_token',
    },
    signal, // <-- pass signal with options
  })
    .then((res) => res.json())
    .then((data) => {
      setPhoto(data.mypost);
    })
    // catch any rejected fetch promises (including aborted fetches!)
    .catch(console.error);

試試下面的代碼:

 useEffect(() => {
let isMounted = true;
 fetch('/mypost', {
  headers: {
    cookie: 'access_token',
  },
})
  .then((res) => res.json())
  .then((data) => {
    if (isMounted)  setPhoto(data.mypost);
  });

//cleanup function
return () => { isMounted = false };
    
}, []);

通用 JSON 獲取演示

import React, {useState} from "react";
import { useAsyncEffect } from "use-async-effect2";
import cpFetch from "cp-fetch";

export default function TestComponent(props) {
  const [photo, setPhoto] = useState([]);

  useAsyncEffect(
    function* () {
      const response = yield cpFetch('/mypost');
      setPhoto((yield response.json()).mypost);
    },
    []
  );

  return <div></div>;
}

暫無
暫無

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

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