diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f07038d..f77149a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Changelog +## v3.5.0 - 2026-06-24 + +### Added + +- **Hooks now run during server rendering (`ui.RenderToString`).** Previously the + string serializer was hook-less: a component calling any hook errored with + "called outside component context", so only hook-free trees could be + server-rendered. `RenderToString` now installs a transient hook fiber per + component, so on the server: + - `GoUseState` returns its initial value (the setter is a no-op); + - `GoUseRef` and `GoUseMemo` compute normally; + - `GoUseContextValue` resolves to the nearest provider's value — context flows + down through host elements and nested providers override correctly; + - `GoUseEffect` is queued but never committed, so effects do not run on the + server (matching React). + + This makes GWC able to server-render real (hook-using) components, matching + React's `ReactDOMServerIntegrationHooks`. Implemented by threading the inherited + context map through the SSR renderer and deriving it at each `ContextProvider` + boundary. Covered by `ui/ssr_hooks_test.go`. + + Notes: SSR-with-hooks uses the package-global current-fiber like the client + reconciler, so a single process renders hook components one tree at a time + (concurrent goroutine SSR of hook components needs external serialization — a + pre-existing hook-architecture constraint). The streaming SSR path runs hooks + but does not yet thread context (a documented follow-up); the buffered + `RenderToString` path is fully supported. + ## v3.4.10 - 2026-06-24 ### Fixed diff --git a/docs/REACT_TEST_PARITY.md b/docs/REACT_TEST_PARITY.md index cdbb7bf6..8bbc4fa5 100644 --- a/docs/REACT_TEST_PARITY.md +++ b/docs/REACT_TEST_PARITY.md @@ -29,7 +29,7 @@ re-renders/effects are observable inline. SSR behavior is tested via | ReactDOMServerIntegrationBasic | basic SSR render, nested components, nil | ✅ | ui/ssr_components_test.go | | ReactDOMServerIntegrationFragment | fragment SSR | ✅ | ui/ssr_components_test.go (component->fragment hoist) | | ReactDOMServerIntegrationSpecialTypes | numbers/bools/null children | 🚫 | Go static typing (ui.Node children) | -| ReactDOMServerIntegrationHooks | hooks under SSR | 🔶 | ui/ssr_hooks_boundary_test.go — ARCHITECTURAL GAP: ui.RenderToString is hook-less; hook/context components render only via the reconciler (RenderInto), which IS tested. String-SSR of hook components errors. Candidate for a dedicated "SSR hooks" feature (transient fiber tree + context propagation + hook server-mode). | +| ReactDOMServerIntegrationHooks | hooks under SSR | ✅ | ui/ssr_hooks_test.go — IMPLEMENTED in v3.5.0: RenderToString runs useState/useRef/useMemo/useContext (effects skipped); context flows + nested providers override. Streaming path: hooks yes, context threading is a follow-up. | | ReactDOMServerIntegrationRefs | refs inert during SSR | ✅ | ui/ssr_ref_and_context_test.go | | ReactDOMServerIntegrationNewContext | context under SSR / multi-consumer | ✅ | ui/ssr_ref_and_context_test.go, ui/context_native_test.go | | ReactDOMServerIntegrationTextarea/Input/Checkbox | controlled inputs SSR | ✅ | ui/ssr_controlled_inputs_test.go (textarea value->content: found+fixed v3.4.9) | diff --git a/examples/public-examples-site/assets/docs/latest-release-notes.md b/examples/public-examples-site/assets/docs/latest-release-notes.md index b12ec10a..e73b62ab 100644 --- a/examples/public-examples-site/assets/docs/latest-release-notes.md +++ b/examples/public-examples-site/assets/docs/latest-release-notes.md @@ -3,18 +3,19 @@ This docs-site page mirrors the first section returned by `tools/changelogcheck.LatestEntry(CHANGELOG.md)`. -## v3.4.10 - 2026-06-24 +## v3.5.0 - 2026-06-24 -The current latest changelog section is `v3.4.10 - 2026-06-24`. **Fixed:** a -controlled ``, so a -server-rendered select showed no initial selection and mismatched on hydration. -The serializer now drops `value` from the `