Docs: Restore React 16/17 support in useServiceDocgen#35179
Merged
Conversation
Replace the React 18-only useSyncExternalStore call with an inlined shim built from useState/useEffect/useLayoutEffect, since addon-docs still supports React 16.8 and 17 which lack that hook. The shim faithfully mirrors React's official use-sync-external-store fallback and is safe on React 16/17 (synchronous rendering, no tearing). Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesInline useSyncExternalStore shim for useServiceDocgen
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes ✨ Finishing Touches📝 Generate docstrings
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #
What I did
A recent change added the
useServiceDocgenhook toaddon-docs, which subscribed docs blocks to the preview's localcore/docgenruntime using React'suseSyncExternalStore. Using React in docs is fine (docs brings in React even in the framework-agnostic preview), butuseSyncExternalStoreonly exists from React 18 onwards, andaddon-docsstill supports React 16.8 and 17 (see thereactrange incode/addons/docs/package.json). This broke those setups.This PR replaces the
useSyncExternalStorecall with an inlined shim built from the older hooks (useState,useEffect,useLayoutEffect), while preserving the exact subscription behavior. The shim is a faithful port of React's officialuse-sync-external-store/shimfallback, which is safe on React 16/17 because those versions render synchronously and therefore can't tear (the tearing problem the real hook guards against only occurs with concurrent rendering, which doesn't exist before React 18).The shim is clearly commented, including a
TODOto delete it and go back to importinguseSyncExternalStorefromreactonce support for React < 18 is dropped.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
Caution
This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!
Manual QA was performed locally against the internal Storybook UI on port 6007 (port 6006 was already in use) with
features.experimentalDocgenServertemporarily enabled — that is the code path that exercisesuseServiceDocgenvia thecore/docgenopen service.Setup (one-time per QA session)
From the repo root, install dependencies if needed:
yarnCompile core if needed:
yarn nx compile coreIn
code/.storybook/main.ts, temporarily setfeatures.experimentalDocgenServertotrue(revert before committing — the internal UI keeps thisfalseby default).Start the internal Storybook UI on a free port (example uses
6007):Open
http://localhost:6007/in a browser.Verify docgen renders on the docs page
primaryrow description reads “Is this the principal call to action on the page?”; other props (label,backgroundColor,size,onClick) also show their JSDoc descriptions.Verify docgen reacts to source file changes
With the Button docs page open, edit
code/addons/docs/src/blocks/examples/Button.tsx.Change the JSDoc on the
primaryprop, for example:Save the file. In the Storybook terminal, confirm a Vite HMR line appears, e.g.
Vite hmr update /addons/docs/src/blocks/examples/Button.tsx.In the Storybook sidebar, click Primary (under addons/docs → Examples → Button), then click Docs again.
Confirm the Controls table
primarydescription updated to “QA test: Is this the principal call to action on the page?” without restarting Storybook.Revert the temporary JSDoc edit in
Button.tsxand restoreexperimentalDocgenServer: falseincode/.storybook/main.ts.React 16/17 regression check (optional, for reviewers with older sandboxes)
useSyncExternalStore is not a function.Documentation
MIGRATION.MD
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsDeclare whether manual QA will be needed for this PR during the next release, through
qa:neededorqa:skipMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>