取消由Context.Consumer创建的useEffect清理功能中的所有订阅

时间:2019-06-13 15:41:29

标签: reactjs react-hooks react-context use-effect

每次执行onClick时,我都会收到一条有关内存泄漏的警告消息。

如何使用useEffect钩子从我的功能组件中的 Context.Consumer 取消订阅?

我没有找到一种方法来退订AppContext。 AppContext.unsubsribe()无效。

import React, {useState, useContext} from 'react';
import {withRouter} from 'react-router-dom';
import axios from 'axios';
import {AppContext} from "../context/AppContext";

const LoginPage = (props) => {

    const [name, setName] = useContext(AppContext);
    const [isLoading, setIsLoading] = useState(false);

    const onClick = () => {
        setIsLoading(true);
        axios.post('/get-name')
            .then(resp => {
                setName(resp);
                setIsLoading(false);
                props.history.push('/');
            })
            .catch(err => console.log(err))
            .finally(() => setIsLoading(false));
    };

    return (
        <div>
            <button onClick={onClick}></button>
        </div>
    );
};

export default withRouter(LoginPage);

浏览器控制台中的错误消息:

  

警告:无法在未安装的状态下执行React状态更新
  零件。这是空操作,但表示您的内存泄漏   应用。要修复,请取消所有订阅和异步任务   在useEffect清理功能中。       在UserPage中(由Context.Consumer创建)       在Route中(由withRouter(UserPage)创建)       在withRouter(LoginPage)中(由Context.Consumer创建)       在Route中(由UserRoute创建)

2 个答案:

答案 0 :(得分:0)

作为警告状态,您需要在UserPage组件中对useEffect进行清理,以避免内存泄漏。

请参见Docs,要求在效果后进行清理。

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

答案 1 :(得分:0)

您的问题是axios返回了promise,因此在安装组件时,单击将执行axios.post(...)。当它然后卸载时(尽管诺言仍然可以“未完成”),其setState的{​​{1}}将在卸载组件后执行。

您可以轻松检查组件是否已安装:

finally