如何检查组件是否已卸载到功能组件中?

bra*_*age 5 reactjs

回调函数设置组件状态。但有时提供数据的订阅需要结束。因为回调是异步执行的,所以它不知道订阅是否在进行服务调用(执行回调函数)后立即结束。

然后我在控制台中看到以下错误:

警告:无法对卸载的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。

有没有办法访问组件状态,即使我在回调函数中?

这将是步骤:

  • 订阅参数
  • 退订
  • 组件被卸载
  • 订阅的服务执行回调函数
  • 回调函数在未安装的组件中设置状态,并在上面给出错误

Moh*_*ami 13

您可以使用这样的引用:

const mounted = useRef(false);

useEffect(() => {
    mounted.current = true;

    return () => { mounted.current = false; };
}, []);
Run Code Online (Sandbox Code Playgroud)

然后在您的回调中,您可以检查是否mounted.current === false并避免设置状态


HMR*_*HMR 5

以下是一些伪代码,如何使用useEffect来查看组件是否已安装。

它使用 useEffect 来侦听,someService当它收到消息时,它会检查组件是否已安装(组件卸载时也会调​​用清理函数),如果是,则使用useStatesetServiceMessage创建的来设置服务接收的消息:

import { useState, useEffect } from 'react';
import someService from 'some-service';

export default props => {
  const userId = props.userId;
  const [serviceMessage, setServiceMessage] = useState([]);
  useEffect(
    () => {
      const mounted = { current: true };
      someService.listen(
        //listen to messages for this user
        userId, 
        //callback when message is received
        message => {
          //only set message when component is mounted
          if (mounted.current) {
            setServiceMessage(serviceMessage.concat(message));
          }
      });
      //returning cleanup function
      return () => {
        //do not listen to the service anymore
        someService.stopListen(userId);
        //set mounted to false if userId changed then mounted
        //  will immediately be set to true again and someService
        //  will listen to another user's messages but if the 
        //  component is unmounted then mounted.current will 
        //  continue to be false
        mounted.current = false;
      };
    },//<-- the function passed to useEffects
    //the function passed to useEffect will be called
    //every time props.userId changes, you can pass multiple
    //values here like [userId,otherValue] and then the function
    //will be called whenever one of the values changes
    //note that when this is an object then {hi:1} is not {hi:1}
    //referential equality is checked so create this with memoization
    //if this is an object created by mapStateToProps or a function
    [userId]
  );
};
Run Code Online (Sandbox Code Playgroud)