React 19 in ONE sites
Islands, not pages
React components are islands. A .tsx only runs in the browser when an .astro mounts it with a directive:
<Counter client:load /> <!-- hydrate immediately -->
<Chart client:visible /> <!-- hydrate when scrolled into view -->
A .tsx with no client:* directive renders to static HTML — no interactivity.
Use @oneie/react hooks for ONE data
import { useSignal, useMark } from '@oneie/react'
function Likes({ pathId }: { pathId: string }) {
const strength = useSignal(pathId, 'strength')
const mark = useMark(pathId)
return <button => mark()}>{strength} ♥</button>
}
Do not useEffect(() => fetch(...)) for ONE data — the hooks own subscription + the closed loop (mark/warn).
React 19 specifics
- Use Actions /
use()/ transitions for async UI; avoid manual loading-stateuseStateladders. - Props named
childrenare reserved slot content — never usechildrenas a data prop on aclient:onlyisland (it silently renders nothing).
Don't
- Don't fetch ONE data in
useEffect— use@oneie/reacthooks. - Don't ship a
.tsxexpecting interactivity without aclient:*directive.