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

@@ -110,6 +110,15 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
}
}, [scrollToTopTrigger, scrollToTopInternal]);
// 使用 ref 保存最新的状态值,避免依赖项变化导致函数重新创建
const showSearchBarRef = useRef(showSearchBar);
const isShowInputCustomerNavBarRef = useRef(isShowInputCustomerNavBar);
useEffect(() => {
showSearchBarRef.current = showSearchBar;
isShowInputCustomerNavBarRef.current = isShowInputCustomerNavBar;
}, [showSearchBar, isShowInputCustomerNavBar]);
// ScrollView 滚动处理
const handleScrollViewScroll = useCallback(
(e: any) => {
@@ -143,12 +152,16 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
const positionThreshold = 120;
const distanceThreshold = 80;
// 使用 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,
@@ -160,7 +173,7 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
(newDirection === "down" && totalScrollDistance > distanceThreshold) ||
currentScrollTop <= positionThreshold
) {
if (!showSearchBar || isShowInputCustomerNavBar) {
if (!currentShowSearchBar || currentIsShowInputCustomerNavBar) {
setShowSearchBar(true);
updateListPageState({
isShowInputCustomerNavBar: false,
@@ -173,12 +186,8 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
lastScrollTopRef.current = currentScrollTop;
lastScrollTimeRef.current = currentTime;
},
[
showSearchBar,
isShowInputCustomerNavBar,
updateListPageState,
onNavStateChange,
]
[updateListPageState, onNavStateChange]
// 移除 showSearchBar 和 isShowInputCustomerNavBar 依赖,使用 ref 获取最新值
);
useEffect(() => {
@@ -196,7 +205,10 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
});
onNavStateChange?.({ isShowInputCustomerNavBar: false });
}
}, [matches, pageOption?.page, updateListPageState, onNavStateChange]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [matches?.length, pageOption?.page]);
// 注意updateListPageState 和 onNavStateChange 是稳定的函数引用,不需要加入依赖项
// 只依赖实际会变化的数据matches 的长度和 pageOption.page
useEffect(() => {
return () => {
@@ -236,9 +248,10 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
duration: 1000,
});
} finally {
setTimeout(() => {
// 使用 requestAnimationFrame 替代 setTimeout(0),性能更好
requestAnimationFrame(() => {
setRefreshing(false);
}, 0);
});
}
};
@@ -252,13 +265,16 @@ const ListPageContent: React.FC<ListPageContentProps> = ({
// 先通知父组件筛选弹窗状态变化(设置 z-index
onFilterPopupVisibleChange?.(newVisible);
// 然后更新本地状态显示/隐藏弹窗
// 使用 setTimeout 确保 z-index 先设置,再显示弹窗
// 使用 requestAnimationFrame 确保 z-index 先设置,再显示弹窗
if (newVisible) {
setTimeout(() => {
updateListPageState({
isShowFilterPopup: newVisible,
// 使用双帧延迟确保 z-index 已生效
requestAnimationFrame(() => {
requestAnimationFrame(() => {
updateListPageState({
isShowFilterPopup: newVisible,
});
});
}, 50);
});
} else {
// 关闭时直接更新状态
updateListPageState({