提问者:小点点

错误:无法对未安装的组件执行React状态更新


我需要你的帮助。我有一个从REST检索数据的组件,当响应返回时,我启用PDF按钮。

const [pdf, setPDF] = useState(false);
const [utente, setUtente] = useState(null);

useEffect(() => {
    const url = ""
    axios.get(url, {
        params: {
            id: props.id
        }
    })
        .then((response) => {
            setPDF(true);
            setUtente(response);
        })
        .catch((err) => {
            setPDF(false);
            setUtente(null);
        });
    return () => {

    };
}, [props.id]);

return (
    <div className="container">
        {
        loadPDF
        ?
        <PDFDownloadLink document={<ComponentPDF utente={utente} />} fileName="utente.pdf">
            { <img src="pdf.png" title="PDF" alt="PDF" /> }
        </PDFDownloadLink>
         :
        <React.Fragment/>
        }
    </div >
);

它工作得很好,但是如果我回到家里,有时我会得到这个错误:

警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。在InternalBlobProvider中(由PDFDownloadLink创建)

有人能帮我吗?

我尝试了您指出的解决方案,但仍然有相同的错误。我的“loadPDF”值为true,这是因为我收到了来自AXIOS的响应。

如果收到AXIOS的响应后,我等待几秒钟,然后我用浏览器返回,我没有这个错误。

如果在AXIOS回复后,我使用浏览器返回,则收到此错误。这是因为PDF组件内部有很多逻辑,可能需要一些时间。

我必须在ComponentePDF中工作吗?


共1个答案

匿名用户

实际情况是,React在卸载组件时尝试更新状态,因此我们需要在卸载组件时取消Axios请求。

为了简单起见,我要从道具中分解id。此外,您可以查看Axios的取消文档,了解如何做到这一点,但我将为您留下以下示例:

useEffect(() => {
    const url = '';

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();

    axios
      .get(url, {
        params: { id },
        cancelToken: source.token,
      })
      .then((response) => {
        setPDF(true);
        setUtente(response);
      })
      .catch((err) => {
        setPDF(false);
        setUtente(null);
      });

    return () => source.cancel();
  }, [id]);