一个基于 Expo + React Native + TypeScript 的移动端问答阅读应用。 覆盖内容社区类产品最常见的前端场景:信息流、内容详情、评论、搜索、收藏,以及 AI 摘要的流式交互。
Insight Pocket 是一个内容阅读类的移动端应用,模拟问答社区的核心体验。它不依赖真实后端,用结构化的本地数据驱动完整的交互流程,重点打磨移动端前端工程的几个关键面:
- 长列表��能 —— 基于
FlatList的虚拟化渲染、React.memo与稳定引用优化 - 流式交互 —— 一个与真实 SSE 接口同构的 AI 摘要状态机(
idle → generating → done | error) - 本地持久化 —— 收藏数据通过
AsyncStorage落盘,并以 Context 跨页面同步 - 完整的状态覆盖 —— 加载(骨架屏)、空状态、错误态、下拉刷新、上拉加载
- 移动端适配 —— 安全区、软键盘、触摸反馈、浅色 / 深色主题
| 页面 | 能力 | 入口文件 |
|---|---|---|
| 发现 Feed | FlatList 长列表、下拉刷新、上拉加载更多、骨架屏占位 |
src/screens/FeedScreen.tsx |
| 问题详情 | 长回答、评论列表、图片全屏预览、AI 摘要流式输出、收藏 | src/screens/DetailScreen.tsx |
| 搜索 | TextInput + 300ms 防抖、热门搜索、加载态、空状态 |
src/screens/SearchScreen.tsx |
| 收藏 | AsyncStorage 本地持久化、跨页面同步、空状态 |
src/screens/FavoritesScreen.tsx |
| 全局 | 浅色 / 深色主题切换、安全区适配、底部 Tab 导航 | src/theme/、src/navigation/ |
| 类别 | 选型 |
|---|---|
| 框架 | Expo SDK 52 / React Native 0.76(New Architecture / Fabric) |
| 语言 | TypeScript(strict 模式) |
| 导航 | React Navigation 7(Bottom Tabs + Native Stack) |
| 持久化 | @react-native-async-storage/async-storage |
| 图片 | expo-image(缓存与淡入过渡) |
| 动画 | 纯 Animated 实现骨架屏 shimmer,未引入额外动画库 |
┌─────────────────────────────────────────────────────────────────────┐
│ App.tsx │
│ Provider 嵌套(外 → 内): │
│ GestureHandlerRootView → SafeAreaProvider → ThemeProvider │
│ → FavoritesProvider │
│ → AppNavigator │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AppNavigator (Native Stack) │
│ │
│ ┌──────────────────────────────┐ ┌─────────────────────────┐ │
│ │ Tabs (Bottom Tab) │ ───▶ │ Detail (Stack push) │ │
│ │ │ │ 问题详情页 │ │
│ │ ┌────────┬────────┬──────┐ │ └─────────────────────────┘ │
│ │ │ Feed │ Search │ Fav │ │ │
│ │ │ 发现 │ 搜索 │ 收藏 │ │ header 右上角:🌙 主题切换 │
│ │ └────────┴────────┴──────┘ │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌──────────────────┐ ┌────────────────────┐
│ Screens │ │ Components │ │ Hooks │
│ │ │ │ │ │
│ FeedScreen │ │ QuestionCard ◀───┼──┤ useFavorites │
│ DetailScreen │ │ StreamingSummary │ │ (+ Context) │
│ SearchScreen │ │ ImagePreview │ │ useDebouncedValue │
│ Favorites │ │ LoadingState │ │ useStreamingSummary│
│ │ │ EmptyState │ │ │
│ │ │ Tag / Avatar │ │ │
│ │ │ ThemeToggle │ │ │
└───────────────┘ └──────────────────┘ └────────────────────┘
│ │ │
└────────────────────┴────────────────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌──────────────────┐ ┌────────────────────┐
│ Theme │ │ Data │ │ AsyncStorage │
│ lightTheme │ │ mockQuestions │ │ (设备本地) │
│ darkTheme │ │ (8 条结构化数据) │ │ 收藏 id 列表 │
│ ThemeContext │ │ │ │ │
└───────────────┘ └──────────────────┘ └────────────────────┘
-
收藏状态:
useFavorites在FavoritesProvider中只实例化一次,通过 Context 下发给 Feed 卡片、详情页与收藏页;任意一处toggleFavorite都会写穿到 AsyncStorage,并让三处视图同步更新。 -
主题切换:
ThemeProvider默认跟随系统useColorScheme,同时支持手动覆盖。主题既下发给所有自定义组件,也桥接进 React Navigation 的容器主题,让导航栏与页面一起换肤。
src/
screens/ # 四个页面:Feed / Detail / Search / Favorites
components/ # QuestionCard / Tag / EmptyState / LoadingState
# StreamingSummary / ImagePreview / Avatar / ThemeToggle
hooks/ # useFavorites(+Context) / useDebouncedValue / useStreamingSummary
navigation/ # Tab + Stack 导航与类型
theme/ # 主题定义与 ThemeContext(含深色模式)
data/ # mockQuestions 结构化数据
types/ # Question / Comment 类型
utils/ # 时间、数字格式化
列表性能
QuestionCard 用 React.memo 包裹,renderItem / keyExtractor 用 useCallback 固定引用,避免父组件重渲染时整列表被动更新。上拉加载用 loadingMore / hasMore 双 flag 拦截 onEndReached 的重复触发与触底���触,footer 明确区分「加载中」与「没有更多了」。
搜索防抖
useDebouncedValue 把输入值与实际过滤值解耦,输入停顿 300ms 才触发过滤。「正在输入但尚未触发」的窗口会显示 loading 提示,体验更贴近远程搜索;清空输入时立即清结果而非等待防抖。
AI 摘要流式
useStreamingSummary 是一个 idle → generating → done | error 状态机,当前以定时器逐字 append 模拟流式输出,但对外暴露的 status / text 接口与真实 SSE 完全一致——接入后端时只需替换数据源,消费 UI 无需改动。组件卸载时清理定时器,避免内存泄漏。
主题系统
ThemeContext 跟随系统并支持手动切换,亮 / 暗双主题集中定义;并桥接进导航容器主题,实现导航栏、背景、状态栏的整体换肤。
npm install
npm start然后任选其一:
- 手机安装 Expo Go,扫描终端二维码
- 按
a启动 Android 模拟器、i启动 iOS 模拟器 - 按
w在浏览器中预览
每次推送 v* 标签时,GitHub Actions 会自动云端构建 Android APK 并发布到 Releases。可直接下载安装到 Android 设备体验。
| 发现 Feed | 问题详情 | 搜索 | 收藏 | 深色模式 |
|---|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
登录注册、真实后端、推荐算法、支付、即时通讯等不在本项目范围内——目标是把「内容消费」这条主线做扎实、做得贴近真实移动端产品的体验。




