Skip to content

Conversation

@renbaoshuo
Copy link
Member

Closes #303

@renbaoshuo renbaoshuo requested a review from a team as a code owner November 7, 2025 02:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the course page to use React Suspense and React Query patterns for better data loading management. The main changes move data fetching logic from component lifecycle methods into a dedicated hook and introduce proper error boundaries.

  • Introduces useCoursePageData hook with React Query's useSuspenseQuery for centralized data fetching
  • Adds error boundary component for graceful error handling
  • Refactors CoursePage from a standalone component into a child component within the main HomePage

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
package.json Adds packageManager field to specify Yarn version
hooks/useCourseDataSuspense.ts New hook that centralizes course data loading with Suspense support
context/course-page.tsx Updates context interface to include schedulesByDays and refetch function
components/course/course-error-boundary.tsx New error boundary component for course page error handling
app/(tabs)/index.tsx Major refactor to use Suspense pattern with nested CoursePage component

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@renbaoshuo renbaoshuo requested a review from Copilot November 7, 2025 04:15
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +127 to +128
// 设置较短的 staleTime,因为我们希望每次进入页面都能检查数据更新
staleTime: 30000, // 30秒
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states the staleTime is set to 30 seconds to check for data updates on each page entry, but this doesn't align with how React Query works. StaleTime of 30 seconds means the data won't be refetched for 30 seconds after being fetched, not that it checks every 30 seconds. If the goal is to check on page focus, consider setting refetchOnWindowFocus: true or reducing staleTime to 0. The current configuration and comment are misleading.

Suggested change
// 设置较短的 staleTime,因为我们希望每次进入页面都能检查数据更新
staleTime: 30000, // 30秒
// 始终检查数据更新:每次进入页面或窗口聚焦时都会重新获取数据
staleTime: 0,
refetchOnWindowFocus: true,

Copilot uses AI. Check for mistakes.
Comment on lines 267 to 273
prevSettingsRef.current = currentSettingsStr;

// 使 React Query 缓存失效,触发重新加载
await queryClient.invalidateQueries({ queryKey: ['course-page-all-data'] });

// 重置组件(触发 Suspense 重新渲染)
setResetKey(prev => prev + 1);
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating prevSettingsRef.current on line 267 before awaiting the async operations creates a timing issue. If the invalidation fails or the component unmounts before completion, the ref will already be updated, preventing retry logic on the next focus. Consider moving line 267 to after line 273, or better yet, use the result of successful invalidation to update the ref.

Suggested change
prevSettingsRef.current = currentSettingsStr;
// 使 React Query 缓存失效,触发重新加载
await queryClient.invalidateQueries({ queryKey: ['course-page-all-data'] });
// 重置组件(触发 Suspense 重新渲染)
setResetKey(prev => prev + 1);
// 使 React Query 缓存失效,触发重新加载
await queryClient.invalidateQueries({ queryKey: ['course-page-all-data'] });
// 重置组件(触发 Suspense 重新渲染)
setResetKey(prev => prev + 1);
// Only update the ref after successful invalidation and reset
prevSettingsRef.current = currentSettingsStr;

Copilot uses AI. Check for mistakes.
});

// 2. 定位当前日期
const locateDateRes = await locateDate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里是会抛异常出来的,是否要像原来那样捕捉一下抛出可读的错误信息

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

queryFn里抛出的异常不会toast出来

Comment on lines +39 to +47
<View className="flex-1 items-center justify-center bg-background p-6">
<Text className="mb-4 text-xl font-semibold text-foreground">加载失败</Text>
<Text className="mb-6 text-center text-muted-foreground">
{this.state.error?.message || '无法加载课表数据,请检查网络连接后重试'}
</Text>
<Button onPress={this.handleReset}>
<Text>重试</Text>
</Button>
</View>
Copy link
Contributor

@klxiaoniu klxiaoniu Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的message是不是会从handleError走一遍以toast等形式出来,可以换成统一的ErrorView组件

<ErrorView refresh={this.handleReset} />

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

queryFn里抛出的异常不会toast出来,要不这里改成toast吧

Comment on lines +276 to +277
// 重置组件(触发 Suspense 重新渲染)
setResetKey(prev => prev + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

只要刷新了就重新渲染,即使课程没变化,会导致页面闪烁(重绘区域比之前大)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

重构课表页面的加载流程

3 participants