fix(violation):修复违规列表重复加载和分页问题

- 将 isLoading 状态改为使用 useRef 避免重复请求
-修复初始加载时的重复请求问题
-优化分页逻辑,避免不必要的重新加载
- 完善生命周期和事件监听处理- 改进列表项 key 的唯一性判断
This commit is contained in:
2025-10-29 13:37:30 +08:00
parent 954c4ac296
commit 164cb594fa

View File

@@ -27,8 +27,8 @@ const List: React.FC = () => {
const [page, setPage] = useState<number>(1)
const [limit, setLimit] = useState<number>(10)
const [total, setTotal] = useState<number>(0)
const [needRefresh, setNeedRefresh] = useState<boolean>(false) // 修改默认值为false避免初始加载时的重复
const [isLoadingRef, setIsLoadingRef] = useState<boolean>(false) // 防止并发加载
const [needRefresh, setNeedRefresh] = useState<boolean>(true)
const isReloadingRef = React.useRef<boolean>(false) // 使用useRef防止并发请求
console.log(refreshing)
// 获取状态显示
@@ -46,22 +46,26 @@ const List: React.FC = () => {
}
const reload = async (showLoading = true) => {
// 防止并发请求,如果正在加载则直接返回
if (isLoadingRef) {
console.log('正在加载中,跳过本次请求')
// 防止并发请求,使用ref而不state避免重渲染
if (isReloadingRef.current) {
console.log('[防重复] 正在加载中,跳过本次请求')
return
}
setLimit(10)
isReloadingRef.current = true
console.log('[开始加载] showLoading:', showLoading, 'page:', page, 'limit:', limit)
// 不要在这里设置limit避免触发useEffect
// setLimit(10) // 删除这行!
try {
setIsLoadingRef(true) // 设置加载标记
if (showLoading) setLoading(true)
setRefreshing(true)
const where: any = {
keywords: keywords.trim(),
page,
limit,
limit: 10, // 直接使用10不通过state
}
const roleCode = Taro.getStorageSync('RoleCode');
@@ -78,15 +82,13 @@ const List: React.FC = () => {
where.code = params.id;
}
console.log('开始请求数据, where:', where)
const res = await pageHjmViolation(where)
console.log('请求成功获取到', res?.list?.length, '条数据')
console.log('[请求成功] 获取到', res?.list?.length, '条数据')
// 确保数据被替换而不是追加
setList(res?.list || [])
setTotal(res?.count || 0)
} catch (error) {
console.error('获取报险记录失败:', error)
console.error('[请求失败]', error)
Taro.showToast({
title: '获取报险记录失败',
icon: 'error'
@@ -94,7 +96,8 @@ const List: React.FC = () => {
} finally {
setLoading(false)
setRefreshing(false)
setIsLoadingRef(false) // 清除加载标记
isReloadingRef.current = false
console.log('[加载结束]')
}
}
@@ -114,41 +117,55 @@ const List: React.FC = () => {
// 页面显示时触发,包括从其他页面返回
useDidShow(() => {
console.log('useDidShow 触发, needRefresh:', needRefresh)
console.log('[生命周期] useDidShow 触发, needRefresh:', needRefresh)
if (needRefresh) {
console.log('执行 reload 由于 needRefresh=true')
reload(false)
console.log('[生命周期] 执行reload 由于 needRefresh=true')
// 先设置false再调用reload防止多次触发
setNeedRefresh(false)
reload(false)
}
})
//
// useEffect(() => {
// // 监听刷新事件
// const handleRefresh = () => {
// console.log('接收到 violationListRefresh 事件')
// // 只设置标记不直接调用reload由useDidShow处理
// setNeedRefresh(true)
// }
//
// Taro.eventCenter.on('violationListRefresh', handleRefresh)
//
// // 初始加载数据 - 只在组件首次挂载时执行
// console.log('组件初始化,执行初始 reload')
// reload().then()
//
// // 清理事件监听器
// return () => {
// Taro.eventCenter.off('violationListRefresh', handleRefresh)
// }
// }, []) // 移除page和limit依赖避免不必要的重新加载
// 单独处理分页变化
// 初始化effect - 只执行一次
useEffect(() => {
if (page > 1 || limit !== 10) { // 只有当分页参数真正改变时才重新加载
console.log('分页参数变化,执行 reload, page:', page, 'limit:', limit)
reload().then()
console.log('[生命周期] 组件初始化')
// 监听刷新事件
const handleRefresh = () => {
console.log('[事件] 接收到 violationListRefresh 事件')
setNeedRefresh(true)
}
}, [page, limit])
Taro.eventCenter.on('violationListRefresh', handleRefresh)
// 初始加载数据
console.log('[生命周期] 执行初始加载')
reload().then()
// 清理事件监听器
return () => {
console.log('[生命周期] 组件卸载,清理事件监听')
Taro.eventCenter.off('violationListRefresh', handleRefresh)
}
}, []) // 空依赖,只执行一次
// 分页变化effect - 单独处理
useEffect(() => {
// 跳过初始值,只在真正变化时才加载
if (page !== 1) {
console.log('[分页变化] page变为', page, '执行reload')
reload()
}
}, [page])
useEffect(() => {
// limit变化时重置到第一页
if (limit !== 10) {
console.log('[分页变化] limit变为', limit, ',重置到第一页')
setPage(1)
reload()
}
}, [limit])
const onPageChange = (current: number) => {
setPage(current)
@@ -223,7 +240,7 @@ const List: React.FC = () => {
return (
<div
key={item.id || item.code} // 使用唯一ID而不是index
key={item.id || item.code || `item-${item.title}-${item.createTime}`} // 使用唯一key
style={{
backgroundColor: '#fff',
borderRadius: '12px',