componentWillUnmount 方法触发场景
- 组件被卸载时:例如,当通过条件渲染控制组件显示与隐藏,条件变化使得组件从页面中移除时触发。比如在一个模态框组件中,当关闭按钮被点击,控制模态框显示的状态发生变化,模态框组件将被卸载,此时会触发
componentWillUnmount
。
- 路由切换导致组件卸载:在单页应用(SPA)中,使用 React Router 等路由库时,当路由发生变化,原路由对应的组件会被卸载,
componentWillUnmount
会被调用。例如从 /home
页面切换到 /about
页面,Home
组件会被卸载。
- 父组件重新渲染导致子组件卸载:如果父组件由于状态变化或属性变化而重新渲染,并且子组件不再满足渲染条件,子组件会被卸载,从而触发
componentWillUnmount
。例如父组件根据某个条件决定是否渲染某个子组件,当条件变化使得子组件不再被渲染时。
通常进行的清理操作
- 清除定时器:如果组件中使用了
setInterval
或 setTimeout
创建定时器,在组件卸载时需要清除,防止内存泄漏。例如:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.timer = null;
}
componentDidMount() {
this.timer = setInterval(() => {
console.log('定时器运行中');
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return <div>组件内容</div>;
}
}
- 取消网络请求:如果组件发起了网络请求,在组件卸载时,若请求还未完成,需要取消请求,避免响应回来后操作已不存在的组件,导致错误。例如使用
axios
库时:
import React, { Component } from'react';
import axios from 'axios';
class MyComponent extends Component {
constructor(props) {
super(props);
this.source = axios.CancelToken.source();
}
componentDidMount() {
axios.get('/api/data', {
cancelToken: this.source.token
}).then(response => {
console.log(response.data);
}).catch(error => {
if (!axios.isCancel(error)) {
console.error(error);
}
});
}
componentWillUnmount() {
this.source.cancel('组件已卸载,取消请求');
}
render() {
return <div>组件内容</div>;
}
}
- 解绑事件监听器:如果在
componentDidMount
中给 DOM 元素添加了事件监听器,在组件卸载时要解绑,防止内存泄漏。例如:
class MyComponent extends React.Component {
handleClick = () => {
console.log('按钮被点击');
}
componentDidMount() {
document.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick);
}
render() {
return <div>组件内容</div>;
}
}