修复 AI 报文解读缓存未在首帧生效的问题

此前 useState 初始化为 idle,useEffect 异步读缓存后才切到 ready,
导致重新打开城市卡片时先闪烁"等待 AI 解读..."再跳转到缓存数据。
现在用 lazy initializer 在首帧同步读取缓存,命中则直接渲染 ready
状态,零闪烁。
This commit is contained in:
2569718930@qq.com
2026-05-06 16:34:19 +08:00
parent 1a40802dcb
commit 59e099a56d
@@ -30,15 +30,20 @@ export function useAiCityForecast({
locale: string; locale: string;
report: string; report: string;
}) { }) {
const [aiForecast, setAiForecast] = useState<AiCityForecastState>({
status: "idle",
});
const [aiRefreshToken, setAiRefreshToken] = useState(0); const [aiRefreshToken, setAiRefreshToken] = useState(0);
const aiForecastKey = useMemo( const aiForecastKey = useMemo(
() => buildAiCityForecastKey({ detail, detailCityName, locale, report }), () => buildAiCityForecastKey({ detail, detailCityName, locale, report }),
[detail, detailCityName, locale, report], [detail, detailCityName, locale, report],
); );
const [aiForecast, setAiForecast] = useState<AiCityForecastState>(() => {
if (!enabled || !aiForecastKey) return { status: "idle" };
const cacheKey = buildAiCityForecastCacheKey(aiForecastKey);
const cached = readReadyCachedAiForecastState(cacheKey, 0);
if (cached) return cached;
return { status: "idle" };
});
useEffect(() => { useEffect(() => {
if (!enabled || !aiForecastKey) { if (!enabled || !aiForecastKey) {
setAiForecast({ status: "idle" }); setAiForecast({ status: "idle" });
@@ -47,16 +52,16 @@ export function useAiCityForecast({
let cancelled = false; let cancelled = false;
const cacheKey = buildAiCityForecastCacheKey(aiForecastKey); const cacheKey = buildAiCityForecastCacheKey(aiForecastKey);
const requestKey = buildAiCityForecastRequestKey(cacheKey, aiRefreshToken); const requestKey = buildAiCityForecastRequestKey(cacheKey, aiRefreshToken);
const readyCachedState = readReadyCachedAiForecastState(
cacheKey, // If cache was loaded into initial state and no force refresh, skip
aiRefreshToken, if (aiRefreshToken === 0) {
); const cached = readReadyCachedAiForecastState(cacheKey, 0);
if (readyCachedState) { if (cached) {
setAiForecast(readyCachedState); setAiForecast(cached);
return () => { return () => { cancelled = true; };
cancelled = true; }
};
} }
const loadingState = buildAiCityLoadingForecastState({ const loadingState = buildAiCityLoadingForecastState({
cacheKey, cacheKey,
detail, detail,