1. componentWillUnmount
- 作用:在组件即将从 DOM 中移除时调用,用于执行一些清理操作,比如取消网络请求、清除定时器、解绑事件监听器等,防止内存泄漏。
- 实际应用场景操作:
- 取消网络请求:如果组件发起了 AJAX 请求,在组件销毁时使用
AbortController
取消未完成的请求。例如:
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.controller = new AbortController();
}
componentDidMount() {
fetch('/api/data', { signal: this.controller.signal })
.then(response => response.json())
.then(data => console.log(data));
}
componentWillUnmount() {
this.controller.abort();
}
render() {
return <div>My Component</div>;
}
}
export default MyComponent;
- **清除定时器**:若组件内部使用了 `setInterval` 或 `setTimeout`,在组件销毁时清除定时器。如:
import React, { Component } from 'react';
class TimerComponent extends Component {
constructor(props) {
super(props);
this.timer = null;
}
componentDidMount() {
this.timer = setInterval(() => {
console.log('Timer is running');
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
render() {
return <div>Timer Component</div>;
}
}
export default TimerComponent;
- **解绑事件监听器**:如果在 `componentDidMount` 中为 `window`、`document` 等添加了事件监听器,在组件销毁时需要解绑。例如:
import React, { Component } from 'react';
class EventComponent extends Component {
handleScroll = () => {
console.log('Window scrolled');
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
render() {
return <div>Event Component</div>;
}
}
export default EventComponent;
2. 从 React v17 开始,getSnapshotBeforeUpdate
与组件销毁的关联(间接相关)
- 作用:
getSnapshotBeforeUpdate
在最近一次渲染输出(提交到 DOM 节点)之前调用。它返回的任何值将作为参数传递给 componentDidUpdate
。虽然不是直接在组件销毁阶段调用,但它返回的值可能会影响到组件销毁时的清理逻辑。
- 实际应用场景操作:
- 保存滚动位置:在列表组件更新时,记录更新前的滚动位置,以便在更新后恢复。假设列表组件可能在数据更新时重新渲染,导致滚动位置丢失。
import React, { Component } from 'react';
class ScrollableList extends Component {
listRef = React.createRef();
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.data.length!== this.props.data.length) {
return this.listRef.current.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot!== null) {
this.listRef.current.scrollTop = snapshot;
}
}
componentWillUnmount() {
// 在这里可以利用之前保存的滚动位置相关信息做一些清理或记录,
// 例如记录用户最后浏览的位置到本地存储等操作
const scrollTop = this.listRef.current.scrollTop;
localStorage.setItem('lastScrollPosition', scrollTop);
}
render() {
return (
<div ref={this.listRef}>
{this.props.data.map((item, index) => (
<div key={index}>{item}</div>
))}
</div>
);
}
}
export default ScrollableList;