我有一个用例,我需要卸载我的 React 组件。但在某些情况下,特定的 react 组件会被不同的函数卸载。因此,我需要在卸载之前检查该组件是否已安装。
有没有办法检查react组件是否已卸载?
由于isMounted()
已被正式弃用,您可以在组件中执行此操作:
componentDidMount() {
this._ismounted = true;
}
componentWillUnmount() {
this._ismounted = false;
}
这种维护自己state
变量的模式在 ReactJS 文档中有详细说明:isMounted is an Antipattern。
我会建议您使用useRef
钩子来跟踪组件是否已安装,因为每当您更新状态时,react 都会重新渲染整个组件,并且还会触发 useEffect 或其他钩子的执行。
function MyComponent(props: Props) {
const isMounted = useRef(false)
useEffect(() => {
isMounted.current = true;
return () => { isMounted.current = false }
}, []);
return (...);
}
export default MyComponent;
然后检查组件是否安装 if (isMounted.current) ...
我认为 Shubham 的答案是 react 为需要转换代码以停止使用isMounted
反模式的人建议的解决方法。
这不一定是坏事,但值得列出这个问题的真正解决方案。
Shubham 链接的文章提供了 2 个避免这种反模式的建议。您需要的取决于您在卸载组件时调用 setState 的原因。
如果您在组件中使用 Flux 存储,则必须在 componentWillUnmount 中取消订阅
class MyComponent extends React.Component {
componentDidMount() {
mydatastore.subscribe(this);
}
render() {
...
}
componentWillUnmount() {
mydatastore.unsubscribe(this);
}
}
如果您使用 ES6 Promise,您可能需要包装您的Promise以使其可取消。
const cancelablePromise = makeCancelable(
new Promise(r => component.setState({...}}))
);
cancelablePromise
.promise
.then(() => console.log('resolved'))
.catch((reason) => console.log('isCanceled', reason.isCanceled));
cancelablePromise.cancel(); // Cancel the promise
makeCancelable
在链接的文章中阅读更多信息。
总之,不要尝试通过设置变量和检查组件是否已安装来修补此问题,请转到问题的根源。如果您能提出任何其他常见案例,请发表评论。
另一种解决方案是使用Refs。如果您使用的是 React 16.3+,请在渲染函数中引用您的顶级项目。
然后简单地检查 ref.current 是否为空。
例子:
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} />
);
}
}
使用@DerekSoike 回答,但是在我的情况下,useState
用于控制安装状态不起作用,因为状态在不需要时复活了
对我有用的是使用单个变量
myFunct
在 a 中被调用setTimeout
,我的猜测是,当同一个组件在另一个页面中初始化钩子时,它会恢复导致内存泄漏再次出现的状态
所以这对我不起作用
const [isMounted, setIsMounted] = useState(false)
useEffect(() => {
setIsMounted(true)
return () => setIsMounted(false)
}, [])
const myFunct = () => {
console.log(isMounted) // not always false
if (!isMounted) return
// change a state
}
这对我有用
let stillMounted = { value: false }
useEffect(() => {
stillMounted.value = true
return () => (stillMounted.value = false)
}, [])
const myFunct = () => {
if (!stillMounted.value) return
// change a state
}