refactor(vega): use useEffectEvent for VegaChart callbacks#3735
Draft
cixzhang wants to merge 1 commit into
Draft
refactor(vega): use useEffectEvent for VegaChart callbacks#3735cixzhang wants to merge 1 commit into
cixzhang wants to merge 1 commit into
Conversation
Replace the onReady/onError ref indirection with useEffectEvent. Both callbacks are invoked only inside the View-lifecycle Effect, so they're a textbook fit for Effect Events: they always see the latest props without being reactive dependencies, so fresh inline callbacks no longer risk re-running the effect and rebuilding the View. Raises the react/react-dom peer floor to >=19.2.0, where useEffectEvent is stable.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
josephfarina
approved these changes
Jul 9, 2026
Contributor
|
CI is red across build/lint/test/docsite-test/smoke-test, but it's all one root cause: the peerDependencies bump to react/react-dom >=19.2.0 wasn't reflected in the lockfile, so The callback migration itself looks clean — onReady/onError go through useEffectEvent, the View lifecycle deps are unchanged, and the fail() path still wraps non-Errors. Note useEffectEvent is React 19.2+, which is why the peerDep bump is needed. |
Contributor
Author
|
CI red |
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.
What
Replace the
onReady/onErrorref-callback pattern inVegaChartwithuseEffectEvent.Before, the callbacks were stashed in refs and reassigned every render so they could be read inside the View-lifecycle Effect without becoming dependencies:
Now they're non-reactive Effect Events:
Behavior is identical: the callbacks always see the latest props, and passing fresh inline callbacks still never re-runs the effect or rebuilds the View. This just expresses the intent with the purpose-built primitive instead of manual ref bookkeeping.
Why only VegaChart?
useEffectEventhas a strict contract — an Effect Event may only be called from inside an Effect, never from an event handler, auseCallback, or during render. I audited every ref-callback site in the codebase against that rule:useEffectEvent?packages/vega/src/VegaChart.tsxuseEffectonlyToast.tsx(onDismiss)setTimeoutreachable from focus/mouse handlersOutline/useScrollSpy.ts(onActiveIdChange)lockActiveIdclick handlerSlider.tsx(onChangeEnd)hooks/useLongPress.ts(onLongPress)useCallback)Chat/useChatNewMessages.ts(onResize)useCallbackTable/.../useTableSortableState.tsx(onSortChange)Chat/useSpeechRecognition.ts,useChatDictation.ts(callbacksRef)Only
VegaChartreads its ref callbacks exclusively inside an Effect, so it's the only place whereuseEffectEventis correct rather than a rules-of-hooks violation. The other sites are legitimately using refs precisely because they fire from event handlers — converting them would trip the "only call from Effects" rule. Leaving them as-is is intentional.Peer dependency bump
useEffectEventis stable as of React 19.2. This raises@astryxdesign/vega'sreact/react-dompeer floor from>=19.0.0to>=19.2.0. (@astryxdesign/vegaisprivate/ canary-only, so no changeset — the changeset gate rejects one for a non-releasable package.)Testing
pnpm -F @astryxdesign/vega typecheck✓pnpm -F @astryxdesign/vega build✓ (declaration emit)pnpm lint✓ (repo checks + eslint; the 2 remaining warnings are pre-existing in unrelated files)