状态管理
状态管理
相关源文件
以下文件为本维基页面的生成提供了上下文:
.github/workflows/nightly-external-dependency-unit-tests.yml.pre-commit-config.yamlbackend/onyx/llm/litellm_singleton/monkey_patches.pybackend/pytest.inibackend/requirements/README.mdbackend/requirements/default.txtbackend/requirements/dev.txtbackend/requirements/ee.txtbackend/requirements/model_server.txtbackend/tests/external_dependency_unit/conftest.pybackend/tests/external_dependency_unit/file_store/test_file_store_non_mocked.pybackend/tests/external_dependency_unit/llm/test_ollama_streaming.pybackend/tests/external_dependency_unit/llm/test_openai_responses_api.pybackend/tests/unit/onyx/llm/test_factory.pybackend/tests/unit/onyx/llm/test_litellm_monkey_patches.pypyproject.tomluv.lockweb/lib/opal/src/components/README.mdweb/lib/opal/src/core/README.mdweb/lib/opal/src/core/index.tsweb/lib/opal/src/core/interactive/README.md- [web/src/app/admin/connector/[ccPairId]/InlineFileManagement.tsx](web/src/app/admin/connector/[ccPairId]/InlineFileManagement.tsx)
web/src/app/components/nrf/SettingsPanel.tsxweb/src/components/context/NRFPreferencesContext.tsxweb/src/lib/constants/chatBackgrounds.tsweb/src/lib/hooks.tsweb/src/providers/AppBackgroundProvider.tsxweb/src/refresh-pages/SettingsPage.tsxweb/src/sections/cards/DocumentSetCard.tsxweb/src/sections/cards/FileCard.tsx
目的与范围
本文档介绍了 Onyx 应用中的前端状态管理模式,重点涵盖自定义 React 钩子(Hook)和状态管理工具,用于处理数据获取、缓存以及客户端状态同步。这些模式主要在 Next.js 前端层实现,并通过 REST 端点与 FastAPI 后端进行协调。
有关后端 API 服务器架构,请参见 8.2 API 服务器架构。有关前端应用结构,请参见 10.1 应用结构与配置。有关状态管理中使用的类型定义,请参见 10.4 类型系统与数据模型。
基于 SWR 的数据获取
Onyx 前端使用 SWR(stale-while-revalidate,过期时重新验证) 作为主要的数据获取和缓存库。SWR 提供了自动缓存、重新验证和乐观更新功能,且样板代码极少。
核心 SWR 钩子
应用提供了大量领域特定的钩子,它们封装了 SWR 以处理不同类型的数据:
| 钩子 | 端点 | 用途 | 刷新能力 |
|---|---|---|---|
usePublicCredentials | /api/manage/admin/credential | 获取连接器的凭证 | refreshCredentials() |
useConnectorStatus | /api/manage/admin/connector/status | 获取完整的连接器状态,30 秒自动刷新 | refreshIndexingStatus() |
useBasicConnectorStatus | /api/manage/connector-status | 获取简化的连接器状态 | refreshIndexingStatus() |
useFederatedConnectors | /api/federated | 获取联邦连接器的详细信息 | refreshFederatedConnectors() |
useLabels | /api/persona/labels | 获取和管理角色标签 | refreshLabels() |
useUserGroups | /api/manage/admin/user-group | 获取用户组(仅企业版) | refreshUserGroups() |
useLLMProviders | /api/llm/provider | 获取用户可访问的大语言模型(LLM)提供商 | refetch() |
useAdminLLMProviders | /api/admin/llm/provider | 获取管理员可查看的完整大语言模型(LLM)提供商视图 | refetch() |
来源:web/src/lib/hooks.ts:44-55, web/src/lib/hooks.ts:209-225, web/src/lib/hooks.ts:227-237, web/src/lib/hooks.ts:239-249, web/src/lib/hooks.ts:265-275, web/src/lib/hooks.ts:277-287
SWR 模式实现
下图展示了使用 SWR 钩子时,React 组件与后端之间的数据流。
SWR 数据流
来源:web/src/lib/hooks.ts:14-15, web/src/lib/hooks.ts:44-55, web/src/lib/hooks.ts:209-225
示例:usePublicCredentials
usePublicCredentials 钩子展示了封装 useSWR 以提供领域特定接口的标准模式:
web/src/lib/hooks.ts:44-55
主要特性:
- 使用
errorHandlingFetcher实现一致的错误处理web/src/lib/hooks.ts:15-15。 - 返回包含
data、error、isLoading的 SWR 响应。 - 提供
refreshCredentials()方法,通过mutate()实现手动缓存失效web/src/lib/hooks.ts:53-53。 - 使用来自
SWR_KEYS的集中式键web/src/lib/hooks.ts:47-47。
来源:web/src/lib/hooks.ts:44-55, web/src/lib/swr-keys.ts:1-20
复杂状态:带分页的连接器索引
useConnectorIndexingStatusWithPagination 钩子实现了一个复杂的分页系统,该系统在支持全局过滤器和自动刷新的同时,维护每个数据源的页面状态。
架构
分页与合并逻辑
来源:web/src/lib/hooks.ts:89-207
状态管理策略
该钩子管理三个关键状态:
- sourcePages:
Record<ValidSources, number>- 跟踪每个数据源的当前页码web/src/lib/hooks.ts:96-98。 - mergedData:
ConnectorIndexingStatusLiteResponse[]- 所有数据源的聚合连接器状态web/src/lib/hooks.ts:99-101。 - sourceLoadingStates:
Record<ValidSources, boolean>- 每个数据源的加载指示器web/src/lib/hooks.ts:103-105。
实现中使用 useRef 在 SWR 获取期间维护分页状态的稳定引用,以避免依赖循环:
web/src/lib/hooks.ts:108-109
来源:web/src/lib/hooks.ts:89-207
过滤器管理系统
useFilters 模式提供了一个全面的过滤器管理系统,用于搜索和文档浏览,并支持 URL 同步。
FilterManager 接口
过滤器状态结构
来源:web/src/lib/hooks.ts:340-479
URL 序列化
该钩子提供了双向 URL 同步:
序列化 通过 getFilterString():
- 将过滤器状态转换为 URL 参数:
&from=...&to=...&sources=...&documentSets=...&tags=...web/src/lib/hooks.ts:369-389。 - 对所有值进行 URL 编码以确保安全。
反序列化 通过 buildFiltersFromQueryString():
- 将 URL 参数解析回过滤器状态
web/src/lib/hooks.ts:401-464。 - 根据可用选项(数据源、文档集、标签)进行校验。
来源:web/src/lib/hooks.ts:340-479
大语言模型(LLM)提供商管理
LlmManager 层级结构实现了复杂的大语言模型(LLM)提供商和模型选择逻辑,支持多个覆盖级别。
大语言模型(LLM)选择层级
系统根据严格的优先级顺序确定活跃的大语言模型(LLM)模型:
模型选择优先级
来源:web/src/lib/hooks.ts:509-541, web/src/lib/hooks.ts:697-738, web/src/hooks/useLanguageModels.ts:46-72
钩子特化
Onyx 为大语言模型(LLM)提供商访问提供了不同的钩子:
useLLMProviders(personaId?):面向用户的标准钩子。通过personaId或组成员身份遵循基于角色的访问控制(RBAC)。使用 60 秒的dedupingIntervalweb/src/hooks/useLanguageModels.ts:46-72。useAdminLLMProviders():面向管理员的钩子。获取完整的LLMProviderView对象,包括 ID 和掩码密钥。禁用revalidateIfStale以防止编辑期间 UI 闪烁web/src/hooks/useLanguageModels.ts:95-114。useWellKnownLLMProvider(providerName):预配置钩子。在保存凭证之前,获取内置提供商(OpenAI、Anthropic 等)的模型列表和建议web/src/hooks/useLanguageModels.ts:129-147。
来源:web/src/hooks/useLanguageModels.ts:1-177
使用 localStorage 的数据源偏好
useSourcePreferences 钩子管理用户对数据源的偏好,并使用 localStorage 在会话之间持久化。
存储与去重
数据源偏好持久化
来源:web/src/lib/hooks.ts:987-1164
getConfiguredSources 中的去重逻辑确保相同类型的索引源和联邦源被同等对待,方法是从唯一键中去除 federated_ 前缀 web/src/lib/hooks.ts:957-985。
工具钩子
useObjectState
一个便捷钩子,用于管理复杂状态对象并支持部分更新,类似于基于类的 setState: web/src/lib/hooks.ts:74-87
useLlmManager
一个中央管理器,用于协调当前模型选择、温度覆盖以及聊天界面中提供商的可用性: web/src/lib/hooks.ts:481-872
来源:web/src/lib/hooks.ts:74-87, web/src/lib/hooks.ts:481-872