Files
deer-flow/frontend/src/app/workspace/chats/[thread_id]/layout.tsx
LofiSu 5d4fd9cf72 fix(frontend): fix new-chat navigation stale state issue (#1077)
- Use router.replace() instead of history.replaceState() so Next.js
  router's internal state is updated on chat start. This ensures
  subsequent "New Chat" clicks are treated as a real cross-route
  navigation (actual-id → "new") rather than a no-op same-path
  navigation, which was causing stale content to persist.

- In ChatLayout, increment the SubtasksProvider key only when
  navigating TO "new" from a non-"new" route. This forces a full
  remount for a fresh new-chat state without remounting when the URL
  transitions from "new" → actual-id (which would interrupt streaming).

Made-with: Cursor

Co-authored-by: DanielWalnut <45447813+hetaoBackend@users.noreply.github.com>
2026-03-11 13:51:51 +08:00

39 lines
1.2 KiB
TypeScript

"use client";
import { useParams } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { PromptInputProvider } from "@/components/ai-elements/prompt-input";
import { ArtifactsProvider } from "@/components/workspace/artifacts";
import { SubtasksProvider } from "@/core/tasks/context";
export default function ChatLayout({
children,
}: {
children: React.ReactNode;
}) {
const { thread_id } = useParams<{ thread_id: string }>();
const prevThreadId = useRef(thread_id);
// Increment only when navigating TO "new" from a non-"new" route.
// This forces a full remount of the subtree for a fresh new-chat state,
// without remounting when the URL transitions from "new" → actual-id
// (which would interrupt streaming).
const [generation, setGeneration] = useState(0);
useEffect(() => {
if (thread_id === "new" && prevThreadId.current !== "new") {
setGeneration((g) => g + 1);
}
prevThreadId.current = thread_id;
}, [thread_id]);
return (
<SubtasksProvider key={generation}>
<ArtifactsProvider>
<PromptInputProvider>{children}</PromptInputProvider>
</ArtifactsProvider>
</SubtasksProvider>
);
}