Combines two related findings from a codebase audit (B2, B4) — same code, same fix.
Problem
B2: `clientSimulator` in `src/App.tsx` (lines 201–236) is a `useMemo` with `viewportSize.width`/`viewportSize.height` as dependencies. Any window resize creates a brand new `BindingSimulator` and calls `clearAllAnalysisState()` inside the memo body — silently wiping collected equilibrium data mid-experiment, just from resizing the browser window.
B4: This is also a React anti-pattern — `setInputConcentration(...)` and `clearAllAnalysisState()` are called directly inside a `useMemo` body as side effects, which React's rules prohibit. This can produce extra renders, torn state, or silently no-op in future React versions.
Severity: High (B2) / Medium (B4)
Fix
- Move simulator instantiation logic so it doesn't blindly react to every pixel of window resize
- Decouple analysis-state clearing from resizing — only clear on real experiment changes (module/section), not window size
- Move the side-effect calls out of the `useMemo` body into a `useEffect` with explicit dependencies
🤖 Filed via Claude Code from a codebase audit.
Combines two related findings from a codebase audit (B2, B4) — same code, same fix.
Problem
B2: `clientSimulator` in `src/App.tsx` (lines 201–236) is a `useMemo` with `viewportSize.width`/`viewportSize.height` as dependencies. Any window resize creates a brand new `BindingSimulator` and calls `clearAllAnalysisState()` inside the memo body — silently wiping collected equilibrium data mid-experiment, just from resizing the browser window.
B4: This is also a React anti-pattern — `setInputConcentration(...)` and `clearAllAnalysisState()` are called directly inside a `useMemo` body as side effects, which React's rules prohibit. This can produce extra renders, torn state, or silently no-op in future React versions.
Severity: High (B2) / Medium (B4)
Fix
🤖 Filed via Claude Code from a codebase audit.