fix(order): stabilize zustand selector snapshots
Move filter-based derivations out of Zustand selectors in order/chat/review detail pages so snapshots stay stable under useSyncExternalStore checks. Add evidence-backed comments referencing React useSyncExternalStore guidance and Zustand issues #1936/#3155 to document the regression trigger.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { ArrowLeft, ImagePlus, Lock, Send } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import Link from "next/link"
|
||||
import { use, useRef, useState } from "react"
|
||||
import { use, useMemo, useRef, useState } from "react"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
@@ -16,7 +16,15 @@ import { useChatStore } from "@/store/chat"
|
||||
export default function ChatDetailPage({ params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = use(params)
|
||||
const session = useChatStore((state) => state.sessions.find((item) => item.id === id))
|
||||
const messages = useChatStore((state) => state.messages.filter((item) => item.sessionId === id))
|
||||
const allMessages = useChatStore((state) => state.messages)
|
||||
// Filter logic runs here via useMemo rather than inside the Zustand selector.
|
||||
// useSyncExternalStore requires a stable snapshot reference on each render.
|
||||
// Inline filter in a selector creates a new array per call and can trigger
|
||||
// infinite re-render loops in Zustand v5 (pmndrs/zustand#1936).
|
||||
const messages = useMemo(
|
||||
() => allMessages.filter((item) => item.sessionId === id),
|
||||
[allMessages, id],
|
||||
)
|
||||
const sendTextMessage = useChatStore((state) => state.sendTextMessage)
|
||||
const sendImageMessage = useChatStore((state) => state.sendImageMessage)
|
||||
const [input, setInput] = useState("")
|
||||
|
||||
Reference in New Issue
Block a user