feat: 定位到组件异常渲染的问题
This commit is contained in:
@@ -66,7 +66,7 @@ const ListPage = () => {
|
||||
const scrollViewRef = useRef(null); // ScrollView 的 ref
|
||||
const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
const lastScrollTopRef = useRef(0);
|
||||
const scrollDirectionRef = useRef<'up' | 'down' | null>(null);
|
||||
const scrollDirectionRef = useRef<"up" | "down" | null>(null);
|
||||
const lastScrollTimeRef = useRef(Date.now());
|
||||
const loadingMoreRef = useRef(false); // 防止重复加载更多
|
||||
const scrollStartPositionRef = useRef(0); // 记录开始滚动的位置
|
||||
@@ -74,45 +74,54 @@ const ListPage = () => {
|
||||
const [scrollTop, setScrollTop] = useState(0); // 控制 ScrollView 滚动位置
|
||||
|
||||
// 动态控制 GuideBar 的 z-index
|
||||
const [guideBarZIndex, setGuideBarZIndex] = useState<'low' | 'high'>('high');
|
||||
const [guideBarZIndex, setGuideBarZIndex] = useState<"low" | "high">("high");
|
||||
const [isPublishMenuVisible, setIsPublishMenuVisible] = useState(false);
|
||||
const [isDistanceFilterVisible, setIsDistanceFilterVisible] = useState(false);
|
||||
const [isCityPickerVisible, setIsCityPickerVisible] = useState(false);
|
||||
|
||||
|
||||
// 处理 PublishMenu 显示/隐藏
|
||||
const handlePublishMenuVisibleChange = useCallback((visible: boolean) => {
|
||||
setIsPublishMenuVisible(visible);
|
||||
}, []);
|
||||
|
||||
|
||||
// 处理 DistanceQuickFilter 显示/隐藏
|
||||
const handleDistanceFilterVisibleChange = useCallback((visible: boolean) => {
|
||||
setIsDistanceFilterVisible(visible);
|
||||
}, []);
|
||||
|
||||
|
||||
// 处理 CityPicker 显示/隐藏
|
||||
const handleCityPickerVisibleChange = useCallback((visible: boolean) => {
|
||||
setIsCityPickerVisible(visible);
|
||||
}, []);
|
||||
|
||||
|
||||
// 滚动到顶部的方法
|
||||
const scrollToTop = useCallback(() => {
|
||||
// 使用一个唯一值触发 scrollTop 更新,确保每次都能滚动到顶部
|
||||
setScrollTop(prev => prev === 0 ? 0.1 : 0);
|
||||
setScrollTop((prev) => (prev === 0 ? 0.1 : 0));
|
||||
}, []);
|
||||
|
||||
|
||||
// 监听所有弹窗和菜单的状态,动态调整 GuideBar 的 z-index
|
||||
useEffect(() => {
|
||||
if (isPublishMenuVisible) {
|
||||
// PublishMenu 展开时,GuideBar 保持高层级
|
||||
setGuideBarZIndex('high');
|
||||
} else if (isShowFilterPopup || isDistanceFilterVisible || isCityPickerVisible) {
|
||||
setGuideBarZIndex("high");
|
||||
} else if (
|
||||
isShowFilterPopup ||
|
||||
isDistanceFilterVisible ||
|
||||
isCityPickerVisible
|
||||
) {
|
||||
// 任何筛选组件或选择器展开时,GuideBar 降低层级
|
||||
setGuideBarZIndex('low');
|
||||
setGuideBarZIndex("low");
|
||||
} else {
|
||||
// 都关闭时,GuideBar 保持高层级
|
||||
setGuideBarZIndex('high');
|
||||
setGuideBarZIndex("high");
|
||||
}
|
||||
}, [isShowFilterPopup, isPublishMenuVisible, isDistanceFilterVisible, isCityPickerVisible]);
|
||||
}, [
|
||||
isShowFilterPopup,
|
||||
isPublishMenuVisible,
|
||||
isDistanceFilterVisible,
|
||||
isCityPickerVisible,
|
||||
]);
|
||||
|
||||
// ScrollView 滚动处理函数
|
||||
const handleScrollViewScroll = useCallback(
|
||||
@@ -133,28 +142,34 @@ const ListPage = () => {
|
||||
if (Math.abs(scrollDiff) > 15) {
|
||||
if (scrollDiff > 0) {
|
||||
// 方向改变时,记录新的起始位置
|
||||
if (newDirection !== 'up') {
|
||||
if (newDirection !== "up") {
|
||||
scrollStartPositionRef.current = lastScrollTop;
|
||||
}
|
||||
newDirection = 'up';
|
||||
newDirection = "up";
|
||||
} else {
|
||||
// 方向改变时,记录新的起始位置
|
||||
if (newDirection !== 'down') {
|
||||
if (newDirection !== "down") {
|
||||
scrollStartPositionRef.current = lastScrollTop;
|
||||
}
|
||||
newDirection = 'down';
|
||||
newDirection = "down";
|
||||
}
|
||||
scrollDirectionRef.current = newDirection;
|
||||
}
|
||||
|
||||
// 计算从开始滚动到现在的累计距离
|
||||
const totalScrollDistance = Math.abs(currentScrollTop - scrollStartPositionRef.current);
|
||||
const totalScrollDistance = Math.abs(
|
||||
currentScrollTop - scrollStartPositionRef.current
|
||||
);
|
||||
|
||||
// 滚动阈值
|
||||
const positionThreshold = 120; // 需要滚动到距离顶部120px
|
||||
const distanceThreshold = 80; // 需要连续滚动80px才触发
|
||||
|
||||
if (newDirection === 'up' && currentScrollTop > positionThreshold && totalScrollDistance > distanceThreshold) {
|
||||
if (
|
||||
newDirection === "up" &&
|
||||
currentScrollTop > positionThreshold &&
|
||||
totalScrollDistance > distanceThreshold
|
||||
) {
|
||||
// 上滑超过阈值,且连续滚动距离足够,隐藏搜索框
|
||||
if (showSearchBar || !isShowInputCustomerNavBar) {
|
||||
setShowSearchBar(false);
|
||||
@@ -164,7 +179,10 @@ const ListPage = () => {
|
||||
// 重置起始位置
|
||||
scrollStartPositionRef.current = currentScrollTop;
|
||||
}
|
||||
} else if ((newDirection === 'down' && totalScrollDistance > distanceThreshold) || currentScrollTop <= positionThreshold) {
|
||||
} else if (
|
||||
(newDirection === "down" && totalScrollDistance > distanceThreshold) ||
|
||||
currentScrollTop <= positionThreshold
|
||||
) {
|
||||
// 下滑且连续滚动距离足够,或者回到顶部附近,显示搜索框
|
||||
if (!showSearchBar || isShowInputCustomerNavBar) {
|
||||
setShowSearchBar(true);
|
||||
@@ -296,7 +314,7 @@ const ListPage = () => {
|
||||
updateFilterOptions(params);
|
||||
};
|
||||
|
||||
const handleSearchChange = () => { };
|
||||
const handleSearchChange = () => {};
|
||||
|
||||
// 距离筛选
|
||||
const handleDistanceOrQuickChange = (name, value) => {
|
||||
@@ -433,7 +451,6 @@ const ListPage = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
{/* 自定义导航 */}
|
||||
<HomeNavbar
|
||||
config={{
|
||||
@@ -467,7 +484,11 @@ const ListPage = () => {
|
||||
{/* 固定在顶部的搜索框和筛选 */}
|
||||
<View className={styles.fixedHeader}>
|
||||
{/* 搜索框 - 可隐藏 */}
|
||||
<View className={`${styles.listTopSearchWrapper} ${showSearchBar ? styles.show : styles.hide}`}>
|
||||
<View
|
||||
className={`${styles.listTopSearchWrapper} ${
|
||||
showSearchBar ? styles.show : styles.hide
|
||||
}`}
|
||||
>
|
||||
<SearchBar
|
||||
handleFilterIcon={toggleShowPopup}
|
||||
isSelect={filterCount > 0}
|
||||
@@ -507,7 +528,11 @@ const ListPage = () => {
|
||||
lowerThreshold={100}
|
||||
onScrollToLower={async () => {
|
||||
// 防止重复调用,检查 loading 状态和是否正在加载更多
|
||||
if (!loading && !loadingMoreRef.current && listPageState?.isHasMoreData) {
|
||||
if (
|
||||
!loading &&
|
||||
!loadingMoreRef.current &&
|
||||
listPageState?.isHasMoreData
|
||||
) {
|
||||
loadingMoreRef.current = true;
|
||||
try {
|
||||
await loadMoreMatches();
|
||||
@@ -529,14 +554,19 @@ const ListPage = () => {
|
||||
error={error}
|
||||
reload={refreshMatches}
|
||||
loadMoreMatches={loadMoreMatches}
|
||||
evaluateFlag
|
||||
/>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
<GuideBar
|
||||
currentPage="list"
|
||||
guideBarClassName={`${styles.guideBarList} ${guideBarZIndex === 'low' ? styles.guideBarLowZIndex : styles.guideBarHighZIndex}`}
|
||||
<GuideBar
|
||||
currentPage="list"
|
||||
guideBarClassName={`${styles.guideBarList} ${
|
||||
guideBarZIndex === "low"
|
||||
? styles.guideBarLowZIndex
|
||||
: styles.guideBarHighZIndex
|
||||
}`}
|
||||
onPublishMenuVisibleChange={handlePublishMenuVisibleChange}
|
||||
/>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user