[GH-ISSUE #695] useEffect callbacks never fire after RSC hydration on Cloudflare Workers (App Router, "use client" pages) #148

Closed
opened 2026-05-06 12:37:39 +02:00 by BreizhHardware · 0 comments

Originally created by @Hitesh-Sisara on GitHub (Mar 27, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/695

Description

useEffect callbacks in "use client" components never execute after RSC hydration when deployed to Cloudflare Workers. Components render correctly (JSX tree appears in DOM, React fiber tree is present), but React's passive effects are never flushed. Any client-side data fetching or side effects inside useEffect simply don't run.

Environment

  • vinext: 0.0.35 (also reproduced on 0.0.27)
  • vite: 8.0.3
  • @cloudflare/vite-plugin: 1.30.1
  • @vitejs/plugin-rsc: 0.5.21
  • react / react-dom: 19.2.4
  • next: 16.0.10
  • Deployment: Cloudflare Workers via wrangler deploy

vite.config.ts

import { defineConfig } from "vite";
import vinext from "vinext";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
  plugins: [
    vinext(),
    cloudflare({
      viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
    }),
  ],
});

Reproduction

Every page in our app is a "use client" component that fetches data via useEffect. Minimal example:

"use client";
import { useState, useEffect } from "react";

export default function MyPage() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    console.log("useEffect fired"); // Never executes
    fetch("https://api.example.com/data")
      .then(res => res.json())
      .then(result => { setData(result.items); setLoading(false); });
  }, []);

  if (loading) return <div>Loading...</div>;
  return <div>{data.length} items</div>;
}

What happens

  1. Page loads via RSC stream — component tree renders correctly in DOM
  2. useEffect callback never fires — no console.log, no fetch, no state update
  3. Page stays stuck showing initial state (empty data)
  4. Chrome DevTools Network tab shows zero API calls to backend after page load
  5. No console errors or warnings

Evidence from Chrome DevTools

We inspected the live deployed site extensively:

  • JS bundles load correctlyworker-entry-*.js, framework-*.js, index-*.js all return 200
  • RSC stream works.rsc responses contain correct component references (I["hash",[],...])
  • React fiber tree exists__reactFiber$* present on DOM elements, component state initialized
  • Component state shows defaults — hooks linked list shows initial values, never updated
  • API is reachable — manually calling fetch() from console returns 200 with data
  • No useEffect execution at all — effects registered in fiber tree (effect.tag === 8) but create() never called

What we tried

  • Upgrading from vinext 0.0.27 to 0.0.35 — same behavior
  • Adding auth state as useEffect dependency — no effect since initial useEffect never fires
  • vinext build completes successfully with all 20 routes detected
  • vinext check reports 94% compatibility with no blocking issues
  • Works perfectly with vinext dev locally — issue only in production on Workers

Expected behavior

useEffect callbacks should execute after RSC hydration completes, matching standard Next.js behavior.

Originally created by @Hitesh-Sisara on GitHub (Mar 27, 2026). Original GitHub issue: https://github.com/cloudflare/vinext/issues/695 ## Description `useEffect` callbacks in `"use client"` components never execute after RSC hydration when deployed to Cloudflare Workers. Components render correctly (JSX tree appears in DOM, React fiber tree is present), but React's passive effects are never flushed. Any client-side data fetching or side effects inside `useEffect` simply don't run. ## Environment - **vinext**: `0.0.35` (also reproduced on `0.0.27`) - **vite**: `8.0.3` - **@cloudflare/vite-plugin**: `1.30.1` - **@vitejs/plugin-rsc**: `0.5.21` - **react / react-dom**: `19.2.4` - **next**: `16.0.10` - **Deployment**: Cloudflare Workers via `wrangler deploy` ## vite.config.ts ```ts import { defineConfig } from "vite"; import vinext from "vinext"; import { cloudflare } from "@cloudflare/vite-plugin"; export default defineConfig({ plugins: [ vinext(), cloudflare({ viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] }, }), ], }); ``` ## Reproduction Every page in our app is a `"use client"` component that fetches data via `useEffect`. Minimal example: ```tsx "use client"; import { useState, useEffect } from "react"; export default function MyPage() { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { console.log("useEffect fired"); // Never executes fetch("https://api.example.com/data") .then(res => res.json()) .then(result => { setData(result.items); setLoading(false); }); }, []); if (loading) return <div>Loading...</div>; return <div>{data.length} items</div>; } ``` ## What happens 1. Page loads via RSC stream — component tree renders correctly in DOM 2. `useEffect` callback **never fires** — no console.log, no fetch, no state update 3. Page stays stuck showing initial state (empty data) 4. Chrome DevTools Network tab shows **zero** API calls to backend after page load 5. No console errors or warnings ## Evidence from Chrome DevTools We inspected the live deployed site extensively: - **JS bundles load correctly** — `worker-entry-*.js`, `framework-*.js`, `index-*.js` all return 200 - **RSC stream works** — `.rsc` responses contain correct component references (`I["hash",[],...]`) - **React fiber tree exists** — `__reactFiber$*` present on DOM elements, component state initialized - **Component state shows defaults** — hooks linked list shows initial values, never updated - **API is reachable** — manually calling `fetch()` from console returns 200 with data - **No useEffect execution at all** — effects registered in fiber tree (`effect.tag === 8`) but `create()` never called ## What we tried - Upgrading from vinext `0.0.27` to `0.0.35` — same behavior - Adding auth state as useEffect dependency — no effect since initial useEffect never fires - `vinext build` completes successfully with all 20 routes detected - `vinext check` reports 94% compatibility with no blocking issues - Works perfectly with `vinext dev` locally — issue only in production on Workers ## Expected behavior `useEffect` callbacks should execute after RSC hydration completes, matching standard Next.js behavior. ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#148
No description provided.