fix: 修复关闭最后一个分屏时 setState-during-render 报错

- removeFromSplit 中 setSplitSessions updater 内直接调用 router.replace
  导致在渲染 AppShell 时触发 Router 组件状态更新
- 改为将导航目标存入 useRef,通过 useEffect 延迟执行 router.replace

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-02-28 13:30:20 +08:00
1 parent 7696cbf5c5
commit f7735e0b9c
1 file changed
+15 -5
+15 -5
View File
@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect, useCallback, useMemo } from "react";
import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import { usePathname, useRouter } from "next/navigation";
import { TooltipProvider } from "@/components/ui/tooltip";
import { NavRail } from "./NavRail";
@@ -208,14 +208,15 @@ export function AppShell({ children }: { children: React.ReactNode }) {
});
}, [sessionId, sessionTitle, workingDirectory]);
const pendingNavigateRef = useRef<string | null>(null);
const removeFromSplit = useCallback((removeId: string) => {
setSplitSessions((prev) => {
const next = prev.filter((s) => s.sessionId !== removeId);
if (next.length <= 1) {
// Exit split mode
// Exit split mode — defer navigation to useEffect
if (next.length === 1) {
// Navigate to the remaining session
router.replace(`/chat/${next[0].sessionId}`);
pendingNavigateRef.current = next[0].sessionId;
}
return [];
}
@@ -225,7 +226,16 @@ export function AppShell({ children }: { children: React.ReactNode }) {
);
return next;
});
}, [router]);
}, []);
// Deferred navigation after split exit (avoids setState-during-render)
useEffect(() => {
if (pendingNavigateRef.current) {
const target = pendingNavigateRef.current;
pendingNavigateRef.current = null;
router.replace(`/chat/${target}`);
}
}, [splitSessions, router]);
const exitSplit = useCallback(() => {
const firstSession = splitSessions[0];