错误:无法在已卸载的组件上执行React状态更新

时间:2020-04-21 13:07:31

标签: reactjs react-native react-router react-hooks

我需要你的帮助。 我有一个从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状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要解决此问题,请在componentWillUnmount方法中取消所有订阅和异步任务。 在InternalBlobProvider中(由PDFDownloadLink创建)

有人可以帮我吗?


我尝试了您指示的解决方案,但仍然有相同的错误。 我的“ loadPDF”值是正确的,这是因为我收到了AXIOS的回复。

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

如果在AXIOS答复后我使用浏览器返回,则收到此错误。 这是因为在Component PDF中有很多逻辑,也许需要一些时间。

我必须使用ComponentePDF吗?

1 个答案:

答案 0 :(得分:1)

正在发生的事情是,在卸载组件时,React会尝试更新状态,因此我们需要在卸载组件时取消Axios请求。

为了简单起见,我将从道具中分解ID。另外,您可以查看Axios上的Cancellation文档,以了解如何执行此操作,但下面的示例将为您提供帮助:

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