-
Notifications
You must be signed in to change notification settings - Fork 30.5k
[react] Make all refs mutable by default #64896
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
dc13350 to
07075da
Compare
ffff287 to
95c7b2e
Compare
|
Inspecting the JavaScript source for this package found some properties that are not in the .d.ts files. babel-plugin-react-html-attrs (unpkg)was missing the following properties:
gatsbyjs__reach-router (unpkg)was missing the following properties:
as well as these 34 other properties...pick, resolve, shallowCompare, startsWith, useBaseContext, useLocationContext, useNavigate, validateRedirect, BaseContext, LocationContext, insertParams, match, navigate, pick, resolve, shallowCompare, startsWith, useBaseContext, useLocationContext, useNavigate, validateRedirect, BaseContext, LocationContext, insertParams, match, navigate, pick, resolve, shallowCompare, startsWith, useBaseContext, useLocationContext, useNavigate, validateRedirect reach__router (unpkg)was missing the following properties:
react-bootstrap-typeahead (unpkg)was missing the following properties:
as well as these 5 other properties...menuItemContainer, useItem, withItem, tokenContainer, withToken react-map-gl (unpkg)was missing the following properties:
react-onclickoutside (unpkg)was missing the following properties:
react (unpkg)was missing the following properties:
tuya-panel-kit (unpkg)was missing the following properties:
wordpress__components (unpkg)was missing the following properties:
as well as these 17 other properties...Line, SearchControl, TextHighlight, ToolbarDropdownMenu, ToolbarItem, useBaseControlProps, CustomGradientPicker, DuotonePicker, DuotoneSwatch, GradientPicker, GuidePage, Line, SearchControl, TextHighlight, ToolbarDropdownMenu, ToolbarItem, useBaseControlProps wordpress__rich-text (unpkg)was missing the following properties:
|
|
I kept MutableRefObject around so that anyone using RefObject in their application code would not have the type change from under them and represented RefObject with MutableRefObject. It seemed like a cleaner deprecation path. I also think if we are making breaking changes for React 19, we should not allow the zero argument version of |
We track this separately in #64920. This PR is not stacking all React 19 changes.
Which other cases?
#64920 will propose its non-existent i.e. only |
13f70c4 to
c018004
Compare
c018004 to
610918c
Compare
610918c to
9f7d98e
Compare
|
Hi @eps1lon. What would be the recommendation for the refs that are handled by React, i.e.: const divRef = React.useRef<HTMLDivElement>(null)
// ...
<div ref={divRef} />If I understand correctly, I don't have an opinion on it, just wondering what is the recommended usage. |
There was never such a restriction that you shouldn't mutate it. React will not read this value so you can write whatever you want into that value. You just need to be aware that React may overwrite what you wrote into the ref. But that would equally apply to all instances where you pass a |
|
Thanks for the reply!
This confuses me a bit, wasn't the interface RefObject<T> {
readonly current: T | null;
}A restriction about not mutating it? |
At the type level, yes. But types are in service to how we want React code to be authored. And there this restriction never existed. |
|
Thanks for the clarification |
Ready for review but won't be merged here and rather in a PR for 19 stacking all changes from #64451
Closes #64855
Closes #64772
Fixes first gotcha in https://twitter.com/mattpocockuk/status/1636098722982404096 (second one will be fixed in #64920).
interface RefObject<T> { - readonly current: T | null + current: T }RefObjectis no longer considered a ref managed by React (i.e. it no longer makescurrentnullable). Instead,currentwill only have the type you declare and be mutable.Historically
RefObjectwas the type returned fromcreateRefso it made sense to always includenullsince that what React does on initialization. The mistake we made was reusing it foruseRefwhich has a different audience (useReffor function components where it can act as "instance variables",createReffor class components where we only care about React managed refs).But now that we moved along it makes sense to fix this incorrect abstraction, take on a breaking change and reduce papercuts going forward.
Migration
@types/*packages to their latest versionsnpx types-react-codemod refobject-defaults ./src(seetypes-react-codemodfor full usage)The remaining fixes should only include libraries shipping their own types. Either these libraries are already compatible with React 19 types and you just need to upgrade them or you should raise an issue on their repositories notifying them that their types are not compatible with React 19.