fix: eliminate queue tab flash on mobile by using useSyncExternalStore
useMediaQuery initialized to false and updated in useEffect, causing a paint where isMobile was false on mobile devices. This rendered the desktop layout first, hiding the queue tab until the effect fired. useSyncExternalStore reads matchMedia synchronously on the client so the correct layout is used on the first render with no extra paint. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2df47658fd
commit
f6fe3815cb
1 changed files with 10 additions and 12 deletions
|
|
@ -1,15 +1,13 @@
|
||||||
import { useState, useEffect } from "react";
|
import { useSyncExternalStore } from "react";
|
||||||
|
|
||||||
export function useMediaQuery(query: string): boolean {
|
export function useMediaQuery(query: string): boolean {
|
||||||
const [matches, setMatches] = useState(false);
|
return useSyncExternalStore(
|
||||||
|
(callback) => {
|
||||||
useEffect(() => {
|
const mq = window.matchMedia(query);
|
||||||
const mq = window.matchMedia(query);
|
mq.addEventListener("change", callback);
|
||||||
setMatches(mq.matches);
|
return () => mq.removeEventListener("change", callback);
|
||||||
const handler = (e: MediaQueryListEvent) => setMatches(e.matches);
|
},
|
||||||
mq.addEventListener("change", handler);
|
() => window.matchMedia(query).matches,
|
||||||
return () => mq.removeEventListener("change", handler);
|
() => false
|
||||||
}, [query]);
|
);
|
||||||
|
|
||||||
return matches;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue