# React Code

> Build client-side React apps with Vite — useEffect cleanup and stale-closure bugs, dependency-array gotchas, Context vs. server-state libraries for API data, Vite environment variables, and testing with Vitest. Scoped to Vite+React client-side apps — NOT Next.js (App Router/Server Components/Server Actions need different guidance). Triggers on "useEffect", "React hook", "stale closure", "dependency array", "Vite env variable", "React Vitest testing".

- Skill: `cwijayasundara/react-code` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add cwijayasundara/react-code`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cwijayasundara/react-code/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: cwijayasundara (https://skillmd.com/u/cwijayasundara)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cwijayasundara/react-code

---


# React (Vite, client-side)

Sources: https://react.dev/learn/synchronizing-with-effects, https://vite.dev/guide/env-and-mode (fetched 2026-07-07 — re-verify if this content seems stale).

**Scope note:** this skill covers Vite+React client-side SPA patterns. If the project is Next.js (App Router, Server Components, Server Actions), this content does not apply — that's a meaningfully different rendering model needing its own guidance, not covered here.

## Quick Reference

- `references/hooks-and-state.md` — `useEffect` cleanup functions, stale-closure bugs (including the classic fetch-race-condition), dependency-array gotchas, when to reach for Context vs. a server-state library for API data.
- `references/vite-and-testing.md` — Vite environment variables (`VITE_` prefix, `.env` file precedence), and Vitest/React Testing Library basics.

## Gotchas (do not skip)

- **A `useEffect` without a cleanup function leaks whatever it set up** — subscriptions, intervals, event listeners, connections. If the setup has a natural "undo" (`disconnect`, `unsubscribe`, `removeEventListener`, `clearInterval`), the effect needs a cleanup function that calls it.
- **React intentionally double-invokes effects in development (Strict Mode)** — setup → cleanup → setup again. This is deliberately surfacing real cleanup bugs, not a framework bug. If an effect breaks under double-invocation, the cleanup is incomplete.
- **Fetches inside `useEffect` can race** — a slow earlier request can resolve after a faster later one and overwrite it with stale data. Use an `ignore` flag set in the cleanup function to discard results from a superseded effect run (see `references/hooks-and-state.md`).
- **Objects/functions created inline are a new reference every render** — putting one directly in a dependency array causes the effect to re-run every render, not just when the "real" value changes. Move them outside the component or memoize them.
- **Only `VITE_`-prefixed environment variables reach client code.** Anything without that prefix is silently `undefined` in `import.meta.env` — this is a deliberate secret-leakage guard, not a bug to work around.

## Not Yet Covered Here (fetch before relying on these topics)

Next.js-specific rendering (Server Components, Server Actions, the App Router's data-fetching model) is explicitly out of scope for this skill — fetch `https://nextjs.org/docs` fresh rather than assuming Vite+React conventions transfer.

