一、场景

如上图所示,tab1-未回复,tab2-已回复+筛选条件仅看未处理
当在tab1时,点击tab2的仅看未处理checkbox,此时需要进行tab2的数据请求(请求已回复&未处理的数据)
二、基础实现
js
const [activeKey, setActiveKey] = useState('replied');
const defaultPageParams = {
page: 1,
rows: 5,
};
const getRepliedData = (params: any) => {
const _params = {
...params
}
if (_params.handleStatus == null) {
delete _params.handleStatus;
}
// 存一份params
//...
}
const getNotReplyData = (params: any) => {
//...
// 存一份params
}
const handleFilterRepliedData = (e: CheckboxChangeEvent) => {
const params: any = {
...defaultPageParams,
handleStatus: e.target.checked ? 0 : null,
};
getRepliedData(params);
}
const getData = (key: string) => {
const params: any = {
...defaultPageParams
};
if (key === 'replied') {
getRepliedData(params);
}
if (key === 'not-reply') {
getNotReplyData(params);
}
};
<Tabs
defaultActiveKey={'not-reply'}
activeKey={activeKey}
onChange={(key) => {
setActiveKey(key);
getData(key);
}}
items={[
{
key: 'not-reply',
label: '未回复',
children: (
<div>未回复内容</div>
),
},
{
key: 'replied',
label: (
<Space>
<div>已回复</div>
<Checkbox onChange={handleFilterRepliedData}>
僅看未處理
</Checkbox>
</Space>
),
children: (
<div>已回复内容</div>
),
},
]}
/>
三、基础实现存在的问题
在tab1直接点击tab2的checkbox,会执行Checkbox的onChange事件,也会执行Tabs的onChange事件,会导致请求了两次接口同时页面上会有数据闪现现象,若Tabs的请求更慢,可能还会导致数据查询异常。
四、优化实现
关键代码:
- Checkbox包一层:
<span style={{ pointerEvents: 'none' }} onClick={(e) => e.stopPropagation()}> - Checkbox加style:
style={{ pointerEvents: 'auto' }} - Checkbox onChange方法添加代码:
e.stopPropagation();
setActiveKey('replied');
js
// 1、改Checkbox的onChange方法
const handleFilterRepliedData = (e: CheckboxChangeEvent) => {
// 避免在未命中該tab的情況下,直接點擊該checkbox請求了兩次接口導致的頁面內容閃現問題
e.stopPropagation();
setActiveKey('replied');
//...
}
<Tabs
//...
items={[
//...
{
key: 'replied',
label: (
<Space>
<div>已回复</div>
{/* 2、改Checkbox视图,解決事件冒泡到tabs的onChange事件 */}
<span style={{ pointerEvents: 'none' }} onClick={(e) => e.stopPropagation()}>
<Checkbox style={{ pointerEvents: 'auto' }} onChange={handleFilterRepliedData}>
僅看未處理
</Checkbox>
</span>
</Space>
),
children: (
<div>已回复内容</div>
),
},
]}
/>