面试题答案
一键面试实现思路
- 处理列表项点击事件:使用
useEventListener
监听每个列表项的点击事件,在点击时更新该项的激活状态。 - 处理列表外点击事件:通过监听
document
的点击事件,判断点击目标是否在列表之外,如果是,则取消所有列表项的激活状态。 - 管理事件绑定和解绑:在组件挂载时绑定事件,在组件卸载时解绑事件,以避免内存泄漏。
关键代码片段
假设使用 React 框架,示例代码如下:
import React, { useState, useEffect } from'react';
// 自定义 useEventListener Hook
const useEventListener = (eventName, handler, element = document) => {
useEffect(() => {
const targetElement = element instanceof Window? window : element;
targetElement.addEventListener(eventName, handler);
return () => {
targetElement.removeEventListener(eventName, handler);
};
}, [eventName, handler, element]);
};
const DynamicList = () => {
const [listItems, setListItems] = useState([
{ id: 1, text: 'Item 1', isActive: false },
{ id: 2, text: 'Item 2', isActive: false },
{ id: 3, text: 'Item 3', isActive: false }
]);
const handleListItemClick = (itemId) => {
setListItems(prevItems => prevItems.map(item =>
item.id === itemId? {...item, isActive:!item.isActive } : item
));
};
const handleOutsideClick = (event) => {
const listElement = document.getElementById('dynamic-list');
if (!listElement ||!listElement.contains(event.target)) {
setListItems(prevItems => prevItems.map(item => ({...item, isActive: false })));
}
};
useEffect(() => {
const listElement = document.getElementById('dynamic-list');
if (listElement) {
listElement.addEventListener('click', (event) => {
const itemId = parseInt(event.target.dataset.itemId);
if (!isNaN(itemId)) {
handleListItemClick(itemId);
}
});
return () => {
listElement.removeEventListener('click', (event) => {
const itemId = parseInt(event.target.dataset.itemId);
if (!isNaN(itemId)) {
handleListItemClick(itemId);
}
});
};
}
}, []);
useEventListener('click', handleOutsideClick);
return (
<div id="dynamic-list">
{listItems.map(item => (
<div key={item.id} data-item-id={item.id} style={{ backgroundColor: item.isActive? 'lightblue' : 'white' }}>
{item.text}
</div>
))}
</div>
);
};
export default DynamicList;
事件绑定和解绑管理
- 自定义
useEventListener
Hook:在useEffect
中使用addEventListener
绑定事件,并返回一个函数,在组件卸载时通过removeEventListener
解绑事件。 - 列表项点击事件:在
useEffect
中为列表元素绑定点击事件,并在返回函数中解绑事件,确保在组件卸载时不会有残留的事件监听。 - 列表外点击事件:通过
useEventListener
监听document
的点击事件,同样会在组件卸载时自动解绑事件,避免内存泄漏。