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:
zetaloop
2026-02-22 09:05:04 +08:00
parent 2ade1780c1
commit acb04a02e7
3 changed files with 24 additions and 6 deletions
+7 -2
View File
@@ -2,7 +2,7 @@
import { ArrowLeft, CheckCircle, Clock, Star } from "lucide-react"
import Link from "next/link"
import { use, useEffect, useState } from "react"
import { use, useEffect, useMemo, useState } from "react"
import OrderActions from "@/components/order-actions"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
@@ -37,7 +37,12 @@ export default function OrderDetailPage({ params }: { params: Promise<{ id: stri
const order = useOrderStore((state) => state.orders.find((item) => item.id === id))
const sessions = useChatStore((state) => state.sessions)
const ensureOrderSession = useChatStore((state) => state.ensureOrderSession)
const reviews = useReviewStore((state) => state.reviews.filter((item) => item.orderId === id))
const allReviews = useReviewStore((state) => state.reviews)
// Filtering is deferred to useMemo after reading the raw store array.
// Zustand v5 compares selector outputs by reference stability.
// Returning a fresh filtered array from the selector can re-trigger updates
// and loop under useSyncExternalStore (pmndrs/zustand#1936, #3155).
const reviews = useMemo(() => allReviews.filter((item) => item.orderId === id), [allReviews, id])
const [nowTs, setNowTs] = useState(Date.now())
useEffect(() => {