refactor(web): React 最佳实践优化 — memo/callback + 目录边界 + 路由增强
- useLogger: useMemo + JSON.stringify 替代 useState 派生 - useIsDark: effectiveTheme 替代 token 色值比较 - useCurrentProject: layouts/ 提升到 shared/hooks/ - ConsoleShell: locale useMemo 缓存 - ConsoleOutlet: 添加 Suspense 边界 - routes: 添加 layout 级 errorElement - Table 组件: operationColumn useMemo + useCallback - ChatPanel: footer 合并为 useCallback, props 传入模型数据 - ChatPage: textModels/conversations useMemo 缓存
This commit is contained in:
@@ -2,12 +2,12 @@ import { DeleteOutlined, MoreOutlined } from "@ant-design/icons";
|
||||
import { Conversations } from "@ant-design/x";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { App, Spin } from "antd";
|
||||
import { useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
|
||||
import type { Conversation } from "../../../shared/api";
|
||||
|
||||
import { useCurrentProject } from "../../layouts/workbench-layout/useCurrentProject";
|
||||
import { createConversation, deleteConversation, fetchConversations } from "../../shared/hooks/use-conversations";
|
||||
import { useCurrentProject } from "../../shared/hooks/use-current-project";
|
||||
import { useModelList } from "../../shared/hooks/use-models";
|
||||
import { ChatPanel } from "./ChatPanel";
|
||||
|
||||
@@ -25,8 +25,13 @@ export function ChatPage() {
|
||||
});
|
||||
|
||||
const { data: modelsData } = useModelList({ pageSize: 200 });
|
||||
const textModels = (modelsData?.items ?? []).filter((m) => m.capabilities.includes("text"));
|
||||
const defaultModelId = textModels[0]?.id;
|
||||
|
||||
const textModels = useMemo(
|
||||
() => (modelsData?.items ?? []).filter((m) => m.capabilities.includes("text")),
|
||||
[modelsData],
|
||||
);
|
||||
|
||||
const defaultModelId = textModels[0]?.id ?? null;
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: (id: string) => deleteConversation(project.id, id),
|
||||
@@ -39,10 +44,10 @@ export function ChatPage() {
|
||||
},
|
||||
});
|
||||
|
||||
const conversations = (data?.items ?? []).map((c: Conversation) => ({
|
||||
key: c.id,
|
||||
label: c.title,
|
||||
}));
|
||||
const conversations = useMemo(
|
||||
() => (data?.items ?? []).map((c: Conversation) => ({ key: c.id, label: c.title })),
|
||||
[data],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="app-chat-page">
|
||||
@@ -54,7 +59,7 @@ export function ChatPage() {
|
||||
activeKey={activeConversationId ?? ""}
|
||||
creation={{
|
||||
onClick: () => {
|
||||
void createConversation(project.id, defaultModelId)
|
||||
void createConversation(project.id, defaultModelId ?? undefined)
|
||||
.then((conv) => {
|
||||
void queryClient.invalidateQueries({ queryKey: CONVERSATIONS_KEY });
|
||||
setActiveConversationId(conv.id);
|
||||
@@ -85,8 +90,10 @@ export function ChatPage() {
|
||||
</div>
|
||||
<ChatPanel
|
||||
conversationId={activeConversationId}
|
||||
defaultModelId={defaultModelId}
|
||||
onConversationCreated={setActiveConversationId}
|
||||
projectId={project.id}
|
||||
textModels={textModels}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user