Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有办法检查react组件是否已卸载?_Javascript_Reactjs - Fatal编程技术网

Javascript 有没有办法检查react组件是否已卸载?

Javascript 有没有办法检查react组件是否已卸载?,javascript,reactjs,Javascript,Reactjs,我有一个用例,需要卸载react组件。但在某些情况下,特定的react组件由不同的函数卸载。 因此,在卸载组件之前,我需要检查组件是否已安装。由于isMounted()已被正式弃用,您可以在组件中执行此操作: componentDidMount() { this._ismounted = true; } componentWillUnmount() { this._ismounted = false; } ReactJS文档中详细介绍了维护自己的状态变量的模式: 我发现该组件将被

我有一个用例,需要卸载react组件。但在某些情况下,特定的react组件由不同的函数卸载。 因此,在卸载组件之前,我需要检查组件是否已安装。

由于
isMounted()
已被正式弃用,您可以在组件中执行此操作:

componentDidMount() { 
  this._ismounted = true;
}

componentWillUnmount() {
   this._ismounted = false;
}

ReactJS文档中详细介绍了维护自己的
状态
变量的模式:

我发现该组件将被卸载,生成这个变量


如果(!this._calledComponentWillUnmount)this.setState({vars})我之所以来到这里,是因为我在寻找一种停止轮询API的方法

不包括
websocket
案例,但不包括轮询案例

我的工作方式

// React component

React.createClass({
    poll () {
        if (this.unmounted) {
            return
        }
        // otherwise, call the api
    }
    componentWillUnmount () {
        this.unmounted = true
    }
})
它起作用了。希望能有帮助


请告诉我,如果你们知道这个=]

的任何失败的测试用例,我认为Shubham答案是react建议的一种解决方法,用于需要转换代码以停止使用
isMounted
反模式的人

这并不一定是坏事,但值得列出这个问题的真正解决方案

提供了两个避免这种反模式的建议。所需的设置取决于卸载组件时调用setState的原因

如果您在组件中使用Flux存储,则必须在componentWillUnmount中取消订阅

如果您使用ES6承诺,您可能需要包装您的承诺以使其可取消

阅读链接文章中有关
makeCancelable
的更多信息


总之,不要试图通过设置变量和检查组件是否已安装来修补此问题,请转到问题的根源。如果你能想出一些常见的例子,请评论一下。

同样的想法,但不是其他的实现

/**
*内部具有异步操作的组件
* 
*@公众
*/
类MyComponent扩展组件{
构造函数(…参数){
//不要忘记super=)
超级(…args);
//注意正确的存储“设置状态”
让originSetState=this.setState.bind(this);
//注释覆盖
this.setState=(…args)=>!this.isUnmounted&&originSetState(…args);
}
/**
*组件安装上没有必要的设置标志
*@公众
*/
组件将卸载(){
//注意设置标志
this.isUnmounted=true;
}
/**
*
*@公众
*/
myCustomAsyncAction(){
//…代码
this.setState({any:'data'});//不关心组件状态
//…代码
}
render(){/*…*/}

}
另一个解决方案将使用。如果使用的是React 16.3+,请在渲染函数中对顶级项进行引用

然后简单地检查ref.current是否为null

例如:

class MyClass extends React.Component {
  constructor(props) {
    super(props);
    this.elementRef = React.createRef();
  }

  checkIfMounted() {
     return this.elementRef.current != null;
  }

  render() {
    return (
      <div ref={this.elementRef} />
    );
  }
}
类MyClass扩展了React.Component{
建造师(道具){
超级(道具);
this.elementRef=React.createRef();
}
checkIfMounted(){
返回this.elementRef.current!=null;
}
render(){
返回(
);
}
}
您可以使用:

myComponent.updater.isMounted(myComponent)
“myComponent”是react组件的实例。 如果组件已安装,则返回'true',如果未安装,则返回'false'

  • 这是不受支持的方法。您最好取消订阅任何异步/事件 在组件上,将卸载
如果使用挂钩:

function MyComponent(props: Props) {
  const [isMounted, setIsMounted] = useState<boolean>(false);

  useEffect(() => {
    setIsMounted(true);
  }, []);

  useEffect(() => {
    return () => {
      setIsMounted(false);
    }
  }, []);

  return (...);
}

export default MyComponent;
功能MyComponent(道具:道具){
常量[isMounted,setIsMounted]=useState(false);
useffect(()=>{
setIsMounted(true);
}, []);
useffect(()=>{
return()=>{
setIsMounted(false);
}
}, []);
回报率(…);
}
导出默认MyComponent;

使用@DerekSoike answer,但是在我的例子中,使用
useState
来控制挂载状态是不起作用的,因为该状态在不需要时会重新出现

对我有效的是使用单个变量

myFunct
是在一个
setTimeout
中调用的,我猜当同一个组件在另一个页面中初始化钩子时,它会恢复导致内存泄漏再次出现的状态

所以这对我不起作用

const[isMounted,setIsMounted]=useState(false)
useffect(()=>{
setIsMounted(true)
return()=>setIsMounted(false)
}, [])
常量myFunct=()=>{
console.log(isMounted)//不总是false
如果(!isMounted)返回
//改变状态
}
这确实对我有用

let stillMounted={value:false}
useffect(()=>{
stillMounted.value=true
return()=>(stillMounted.value=false)
}, [])
常量myFunct=()=>{
如果(!stillMounted.value)返回
//改变状态
}

我建议您不要使用
useState
钩子来跟踪组件是否已安装
,因为无论何时更新状态,react都会重新呈现整个组件,并且还会触发useEffect或其他钩子的执行

function MyComponent(props: Props) {
  const isMounted = useRef(false)

  useEffect(() => {
    isMounted.current = true;
    return () => { isMounted.current = false }
  }, []);

  return (...);
}

export default MyComponent;

谢谢你的提示。。。从文件中。。。只需在componentDidMount中将_isMounted属性设置为true,并在componentWillUnmount中将其设置为false。。。但是,使用这个.setState({mounted:false});由于状态更改不会立即发生,因此触发可能太晚而无法阻止警告-最好只为此使用类属性。。。this.mounted=false-谢谢,这为我指明了正确的方向direction@danday74是的,你是对的。我写答案时可能没有抓住要点。考虑一下是否投票helped@KevinGhaboosi,不幸的是,只有提出问题的人才能接受这个答案。这是一个内部属性,我认为与他们玩不安全,因为它可能会在未来发生变化。老实说,在更新库之前是安全的,所以在某些情况下,这是一个很好的解决办法。
function MyComponent(props: Props) {
  const [isMounted, setIsMounted] = useState<boolean>(false);

  useEffect(() => {
    setIsMounted(true);
  }, []);

  useEffect(() => {
    return () => {
      setIsMounted(false);
    }
  }, []);

  return (...);
}

export default MyComponent;
function MyComponent(props: Props) {
  const isMounted = useRef(false)

  useEffect(() => {
    isMounted.current = true;
    return () => { isMounted.current = false }
  }, []);

  return (...);
}

export default MyComponent;