-
Notifications
You must be signed in to change notification settings - Fork 47k
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
Document legacyness of the return value of ReactDOM.render() #6400
Conversation
6ce27f3
to
c8b5e25
Compare
> | ||
> `ReactDOM.render()` currently returns a reference to the root ReactComponent instance. However, using this return value is legacy | ||
> and should be avoided. If you need a reference to the root ReactComponent instance, the preferred solution is to attach a | ||
> [callback ref](/react/docs/more-about-refs.html#the-ref-callback-attribute) to the root 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.
What's the difference between a callback ref and the value provided to the optional callback function to ReactDOM.render?
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.
For the purposes of getting a reference to the root node, I think they're both semantically equivilant. The optional callback was introduced before callback refs were a thing. For consistency, I think we would want to teach refs as the standard way of getting a reference to an instance.
However, callback refs and the optional callback are not identical with regards to their other semantics. The optional callback will be fired when the render completes, whereas the callback ref will only be fired when a component mounts/unmounts. So their behavior is the same for initial mount, but different for updates. Realistically, now that we have callback refs, the optional callback probably isn't very useful, but there are still some potential use cases if you wanted to know when a particular update/render has fully completed.
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.
Thanks for the explanation, @jimfb.
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.
We should add a small example here. Like this:
// Before:
var instance = ReactDOM.render(<App />, rootEl);
doSomethingWithInstance(instance);
// After:
ReactDOM.render(<App ref={doSomethingWithInstance} />, rootEl);
@@ -161,6 +161,10 @@ If the optional callback is provided, it will be executed after the component is | |||
> `ReactDOM.render()` does not modify the container node (only modifies the children of the container). In | |||
> the future, it may be possible to insert a component to an existing DOM node without overwriting | |||
> the existing children. | |||
> | |||
> `ReactDOM.render()` currently returns a reference to the root ReactComponent instance. However, using this return value is legacy |
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.
Let’s put ReactComponent
in backticks. I would also rephrase to clarify: "currently returns a reference to the root ReactComponent
instance that was mounted as a result of this call."
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.
I think it’s good to explain why we ask people to change their code. I would change "using this return value is legacy" to "we are deprecating this way of accessing the root component instance because in the future React might render components asynchronously in some cases."
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.
I don't want to use the word "deprecating" because we have a policy that we only mark something as "deprecated" when it's removal is imminent for the next release. But I do like your additional explanation, so I'll work that into the message.
Would it be premature to add a rule for this to https://github.com/yannickcr/eslint-plugin-react/ start filtering this information out to the community? |
👍 I think it’s a good idea. This would be a breaking change for them tho? If it becomes a default. @iamdustan |
@jimfb I’m accepting on the condition you address the above comments. Thanks! |
c8b5e25
to
01bab11
Compare
01bab11
to
ceb3772
Compare
Document legacyness of the return value of ReactDOM.render() (cherry picked from commit 1dc7c58)
This should probably be considered along with ReactDOM.renderToString and ReactDOM.renderToStaticMarkup. Would those necessarily not be able to synchronously return the string markup too (assuming an async render is allowed)? If that is true, then would they return a promise, observable, or use a new cb parameter to obtain the html? So whatever is decided for those, maybe a similar mechanism should be allowed for ReactDOM.render for symmetry. Meaning if renderToString and renderToStaticMarkup both return a promise which eventually resolves to the html, maybe render should return a promise which eventually resolves to the component. Likewise if observable or cb mechanism is chosen. This is an alternative to using the ref cb. It is nice to have symmetry as much as possible in these api's. Developers have enough other things to worry about. |
I think |
@gaearon beat me to the punch. His answer is exactly correct. 👍 |
ok, thanks. That answers my question. |
As documented initially in facebook/react#6400 and on the documentation website at http://facebook.github.io/react/docs/top-level-api.html#reactdom.render
As documented initially in facebook/react#6400 and on the documentation website at http://facebook.github.io/react/docs/top-level-api.html#reactdom.render
As documented initially in facebook/react#6400 and on the documentation website at http://facebook.github.io/react/docs/top-level-api.html#reactdom.render
A quick follow-up that a rule for this has landed in eslint-plugin-react. jsx-eslint/eslint-plugin-react#586 |
In light of #11401, attaching a callback ref to the root component may cease to carry the desired semantics here. As such, should the guidance instead be updated to be to use the callback from |
Hmm could you clarify what would change? |
(To be clear I don't think there was a team consensus to implement #11401 specifically—it was just one of proposals and IMO a somewhat extreme one.) |
I mean "use the optional Though this problem would sort of go away if |
Document legacyness of the return value of ReactDOM.render(), as per #6397