fix(web): t-Falle in acht Ladeeffekten entschaerft, RssFeedListForm/SavedSearchBar-Ladefunktionen stabilisiert
Befunde 7-15 der Biome-Regel useExhaustiveDependencies (quick-260921-gof): - VehicleTable, TenderDetail, DigestIntervalForm, SourceConfigForm, favorites-widget: Ersatz-Fehlertext aus useTranslations wird jetzt vor dem Effekt/Rueckruf in eine Konstante gezogen und diese Konstante in die Abhaengigkeitsliste aufgenommen - `t` selbst kommt nirgends mehr in eine Liste. In diesem Projekt ist belegt, dass `t` bei jedem Durchlauf eine frische Funktion ist (Testattrappen), eine `t`- Abhaengigkeit haette den jeweiligen Mount-Abruf zur Schleife gemacht. - RssFeedListForm.tsx und SavedSearchBar.tsx: die Ladefunktionen waren gewoehnliche Funktionen im Rumpf (bei jedem Durchlauf neu) - jetzt in einen stabilen Rueckruf mit der Text-Konstante als einziger Abhaengigkeit eingepackt. - ResultsList.tsx: Befund 8 (t) wie oben, Befund 15 (refreshKey) in den Effekt verschoben, der `load` aufruft, statt in `load` selbst zu stehen - eine begruendete `biome-ignore`-Zeile (erste im Projekt) haelt fest, dass der Auffrisch-Ausloeser der Elternseite ohne diese Abhaengigkeit wirkungslos waere. - Sieben Testdateien um eine Zaehlprobe erweitert: erneutes Zeichnen mit unveraenderten Props darf keinen weiteren Abruf ausloesen; ResultsList zusaetzlich um eine Probe, dass ein refreshKey-Bump genau einen weiteren Abruf ausloest. - DigestIntervalForm hat keine Testdatei - nur am laufenden System auf Meine Quellen geprueft (siehe SUMMARY). - Wirkungslose eslint-disable-Zeilen fuer diese Regel entfallen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
@@ -559,4 +559,18 @@ describe('FavoritesWidget', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('quick-260921-gof (Befund 14): erneutes Zeichnen mit gleicher instanceId loest KEINEN weiteren Abruf aus — die Uebersetzungs-Attrappe liefert bei jedem Durchlauf eine frische Funktion, eine Rueckkehr von `t` in die Abhaengigkeitsliste faellt hier sofort auf', async () => {
|
||||
const { rerender } = render(
|
||||
<FavoritesWidget instanceId="fav-1" config={{}} isEditMode={false} />,
|
||||
);
|
||||
|
||||
await waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(1));
|
||||
|
||||
rerender(
|
||||
<FavoritesWidget instanceId="fav-1" config={{}} isEditMode={false} />,
|
||||
);
|
||||
|
||||
await waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(1));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -96,6 +96,11 @@ export function FavoritesWidget({
|
||||
[favorites],
|
||||
);
|
||||
|
||||
// Befund 14 (quick-260921-gof): Ersatztext vor dem Effekt bestimmt, `t`
|
||||
// selbst bleibt aussen vor — die Testattrappe liefert bei jedem Durchlauf
|
||||
// eine frische Funktion, das wuerde den Mount-Abruf zur Schleife machen.
|
||||
const favoritesErrorText = t('favorites.error');
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
@@ -106,7 +111,7 @@ export function FavoritesWidget({
|
||||
const data = await fetchFavorites(instanceId);
|
||||
if (!cancelled) setFavorites(data);
|
||||
} catch {
|
||||
if (!cancelled) setError(t('favorites.error'));
|
||||
if (!cancelled) setError(favoritesErrorText);
|
||||
} finally {
|
||||
if (!cancelled) setLoading(false);
|
||||
}
|
||||
@@ -117,10 +122,7 @@ export function FavoritesWidget({
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
// instanceId is the only meaningful dependency — t is stable at runtime
|
||||
// and excluded to prevent re-fetching on every render (mock creates new fn)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [instanceId]);
|
||||
}, [instanceId, favoritesErrorText]);
|
||||
|
||||
function getFallbackLetter(title: string): string {
|
||||
const clean = title.trim();
|
||||
|
||||
Reference in New Issue
Block a user