面试题答案
一键面试在React组件中,可以通过useEffect
钩子结合useRef
钩子以及componentWillUnmount
(在类组件中)来处理这种情况。以下是函数组件和类组件的示例:
函数组件
import React, { useEffect, useRef } from 'react';
const TimerComponent = () => {
const intervalRef = useRef(null);
const eventListenerRef = useRef(null);
useEffect(() => {
// 设置定时器
intervalRef.current = setInterval(() => {
console.log('定时器在运行');
}, 1000);
// 订阅外部事件
const handleExternalEvent = () => {
console.log('外部事件被触发');
};
window.addEventListener('resize', handleExternalEvent);
eventListenerRef.current = handleExternalEvent;
// 清理副作用
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
if (eventListenerRef.current) {
window.removeEventListener('resize', eventListenerRef.current);
}
};
}, []);
return <div>定时器和事件订阅示例组件</div>;
};
export default TimerComponent;
类组件
import React, { Component } from 'react';
class TimerClassComponent extends Component {
constructor(props) {
super(props);
this.intervalRef = null;
this.eventListenerRef = null;
}
componentDidMount() {
// 设置定时器
this.intervalRef = setInterval(() => {
console.log('定时器在运行');
}, 1000);
// 订阅外部事件
const handleExternalEvent = () => {
console.log('外部事件被触发');
};
window.addEventListener('resize', handleExternalEvent);
this.eventListenerRef = handleExternalEvent;
}
componentWillUnmount() {
if (this.intervalRef) {
clearInterval(this.intervalRef);
}
if (this.eventListenerRef) {
window.removeEventListener('resize', this.eventListenerRef);
}
}
render() {
return <div>定时器和事件订阅示例类组件</div>;
}
}
export default TimerClassComponent;
在函数组件中,useEffect
返回的清理函数会在组件卸载时执行,用于清理定时器和移除事件监听器。在类组件中,componentWillUnmount
方法在组件卸载时执行相同的清理操作,从而避免内存泄漏。