Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork246
[internal] Remove unneededuseEventCallback
usage#2917
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
pkg-pr-newbot commentedOct 4, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
commit: |
netlifybot commentedOct 4, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
✅ Deploy Preview forbase-ui ready!
To edit notification comments on pull requests, go to yourNetlify project configuration. |
mui-bot commentedOct 4, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Bundle size report
|
ae1f9f5
to79b332d
Compare79b332d
to2da7ddf
Compareconst{ children, elementsRef, labelsRef, onMapChange}=props; | ||
const{ children, elementsRef, labelsRef,onMapChange:onMapChangeProp}=props; | ||
constonMapChange=useEventCallback(onMapChangeProp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Why is this change beneficial?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It aligns with what theuseEffectEvent
linter wants
constregisterControlRef=useEventCallback((element:HTMLButtonElement|null)=>{ | ||
constregisterControlRef=React.useCallback((element:HTMLButtonElement|null)=>{ | ||
if(controlRef.current==null&&element!=null&&!element.hasAttribute(PARENT_CHECKBOX)){ | ||
controlRef.current=element; | ||
} | ||
}); | ||
},[]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Why is this changed?useEventCallback
makes the intent more clear and is more performant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
@michaldudak wrote thatuseCallback
can be more performant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It makes sense now that I re-read the source code,useEventCallback
has to deal with init/render cycles. We could add something likeuseUntrackedCallback
(name tbd) as a version ofReact.useCallback
for functions without tracked dependencies like this one.
constreset=useEventCallback(()=>{ | ||
constreset=React.useCallback(()=>{ | ||
setOpenMethod(null); | ||
}); | ||
},[]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Idem, why move touseCallback
?
The React team often makes decisions that align mostly with Meta's internal needs, and they've stopped putting much effort & thought into the external DX (which the react-hooks eslint package is part of). I wouldn't read too much into why they took that decision.
The code example you listed does runtime type detection and calls both |
@romgrk yeah the overload isn't great, which is why I wrote about What do you think about renaming constcallback=useUntracked(()=>{});constgetValue=useUntracked(()=>prop); |
Signed-off-by: atomiks <cc.glows@gmail.com>
I think that name is confusing. The "callback" token is fairly important semantically. I would instead suggest |
atomiks commentedOct 7, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@romgrk it's the term used to turn off reactivity in every other library (Svelte, Solid, Preact, Angular, Vue, ...). It's just that returning values from
Somewhat, but |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Can we document theuseEffectEvent
and explain when it should be used? To have at least some kind of guidelines for other contirbutors.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
I was going to do this in a new PR. This one doesn't create any new hooks/utils yet, just cleans up the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Changes make sense 👌 I haven't check the whole codebase to find other occurences, but if there is anything missed we can potentially fix those afterwards.
1f62103
intomui:masterUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
After React 19.2 introduced
useEffectEvent
I decided to investigate why we're usinguseEventCallback
(which is a broader version of it without linting restrictions) to see how we could migrate to it or why the React team chose to keep it restricted.Firstly, I removed most instances where it's truly unnecessary as no memoization is occurring.
Secondly, I found various use cases where it directly matches
useEffectEvent
's intended purpose — an event handler that's invoked inside an effect. Or in one special case, used to stabilize a function used as a dependency of an effect.The use cases I found that are broader than the hook's intended purpose:
undefined
value into a NOOP functionWe also have
useLatestRef
, which is a non-function version of making an "untracked" helper. Most other libraries provide this built-in:https://x.com/rickhanlonii/status/1974118493185540588.If the React team weren't wary of wholesale turning off reactivity for something (other libraries provide this already),
useEffectEvent
could've been calleduseUntracked
to have the broadest set of use cases.useEffectEvent
also allows you to access non-reactive non-function values since it respects return values:A
useUntracked
helper that handles all non-reactive values simultaneously, merginguseLatestRef
anduseEventCallback
together, needs an overloaded return value, which is probably not as neat as just renaminguseEventCallback
to something similar touseEffectEvent
but allowing us to bypass its restrictive lint rule to solve our broader use cases (outlined above in the ordered list)@romgrk
If
useUntracked
only returned function values and respected return values, that could work nicely. We could removeuseLatestRef
as a utility in this case.