This commit is contained in:
张成
2025-11-16 09:53:24 +08:00
parent 6f4900eb0b
commit ad971796ba
8 changed files with 143 additions and 64 deletions

View File

@@ -123,6 +123,15 @@ const ListPage = () => {
isCityPickerVisible,
]);
// 使用 ref 保存最新的状态值,避免依赖项变化导致函数重新创建
const showSearchBarRef = useRef(showSearchBar);
const isShowInputCustomerNavBarRef = useRef(isShowInputCustomerNavBar);
useEffect(() => {
showSearchBarRef.current = showSearchBar;
isShowInputCustomerNavBarRef.current = isShowInputCustomerNavBar;
}, [showSearchBar, isShowInputCustomerNavBar]);
// ScrollView 滚动处理函数
const handleScrollViewScroll = useCallback(
(e: any) => {
@@ -165,13 +174,17 @@ const ListPage = () => {
const positionThreshold = 120; // 需要滚动到距离顶部120px
const distanceThreshold = 80; // 需要连续滚动80px才触发
// 使用 ref 获取最新值,避免依赖项变化
const currentShowSearchBar = showSearchBarRef.current;
const currentIsShowInputCustomerNavBar = isShowInputCustomerNavBarRef.current;
if (
newDirection === "up" &&
currentScrollTop > positionThreshold &&
totalScrollDistance > distanceThreshold
) {
// 上滑超过阈值,且连续滚动距离足够,隐藏搜索框
if (showSearchBar || !isShowInputCustomerNavBar) {
if (currentShowSearchBar || !currentIsShowInputCustomerNavBar) {
setShowSearchBar(false);
updateListPageState({
isShowInputCustomerNavBar: true,
@@ -184,7 +197,7 @@ const ListPage = () => {
currentScrollTop <= positionThreshold
) {
// 下滑且连续滚动距离足够,或者回到顶部附近,显示搜索框
if (!showSearchBar || isShowInputCustomerNavBar) {
if (!currentShowSearchBar || currentIsShowInputCustomerNavBar) {
setShowSearchBar(true);
updateListPageState({
isShowInputCustomerNavBar: false,
@@ -197,7 +210,8 @@ const ListPage = () => {
lastScrollTopRef.current = currentScrollTop;
lastScrollTimeRef.current = currentTime;
},
[showSearchBar, isShowInputCustomerNavBar, updateListPageState]
[updateListPageState]
// 移除 showSearchBar 和 isShowInputCustomerNavBar 依赖,使用 ref 获取最新值
);
useEffect(() => {
@@ -216,7 +230,10 @@ const ListPage = () => {
isShowInputCustomerNavBar: false,
});
}
}, [matches, pageOption?.page, updateListPageState]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [matches?.length, pageOption?.page]);
// 注意updateListPageState 是稳定的函数引用,不需要加入依赖项
// 只依赖实际会变化的数据matches 的长度和 pageOption.page
// 清理定时器
useEffect(() => {
@@ -280,10 +297,10 @@ const ListPage = () => {
duration: 1000,
});
} finally {
// 使用 setTimeout 确保状态更新在下一个事件循环中执行,让 ScrollView 能正确响应
setTimeout(() => {
// 使用 requestAnimationFrame 替代 setTimeout(0),性能更好
requestAnimationFrame(() => {
setRefreshing(false);
}, 0);
});
}
};