You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Apologies in advance if this has already been reported. I did my best to thoroughly search through existing issues before posting this, but could not find something this specific. I'd be happy to move/close this as needed. This is (hopefully) more nuanced than the issue about "my render method threw and React blew up, why?" that I mostly encountered.
If a child component throws in its render method, and attempts to be rendered more than once, React throws an uncaught error inside of its internal _updateRenderedComponent method. Depending on the context, this error is either:
Uncaught TypeError: Cannot read property 'getNativeNode' of null
Uncaught TypeError: Cannot read property '_currentElement' of null
Let's say we have a problematic component A. When A renders it throws a runtime error.
Some parent component renders A. During the first render, we see the error that A threw while rendering. This is as expected and is a userland error.
If we attempt to render the parent again, and therefore again render A, we get a different exception. This is where we see Uncaught TypeError: Cannot read property 'getNativeNode' of null from React (or the one referring to _currentElement).
The difference between exceptions #1 (getNativeNode) and #2 (_currentElement) is that #1 happens when component A is the same between each render; #2 happens when component A is swapped in the second render with another component that also happens to throw while rendering. The latter is more likely as we move from a loaded -> error handler view, where the error view may unfortunately also throw.
Why would you render a broken twice? Well, consider something as simple as this:
classAppLoadedextendsReact.Component{render(){thrownewError('I throw!')}}// Supposed to gracefully render an error, but it happens to throw.classGracefulErrorextendsReact.Component{render(){thrownewError('Dang, I also throw :(')}}classMainextendsReact.Component{constructor(props,ctx){super(props,ctx)this.state={loaded: false,error: null,}}componentDidMount(){// Do some async work...// NOTE: This living inside of a promise is not vital to reproduction, but// it is what originally caused me to go down the path of discovering// the issue. See minimal test cases for examples w/o promises.returnPromise.resolve()// do some async work.then(()=>{this.setState({loaded: true})})// Yes, this really should not be in `catch`, but there are valid scenarios// for code like this to exist. This is just to demonstrate the issue.// See explanations below..catch((err)=>{this.setState({error: true})})}render(){if(this.state.error)return<GracefulError/>if(this.state.loaded)return<AppLoaded/>return<h1>Loading</h1>}}
This is what led to the discovery of this bug. The promise handling here is technically incorrect, since what we really meant was to use .then(onSuccess, onFailure) so that we didn't implicitly catch synchronous render errors caused by the setState call in the onSuccess callback. However, I do believe there are valid scenarios where this occurs, such as when manually handling a render error, but where the recovering component rendered in its place also (unfortunately) throws and consequently leads to this untraceable error.
What is the expected behavior?
React should not blow up with this internal/untraceable error on the second render. I'm not even sure if this is possible, but at a minimum I'd like to better understand why this occurs.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Browser: Google Chrome Version 58.0.3029.81 (64-bit)
React:
v15.1.0
v15.3.2
v15.5.0
Those are just the versions I've tested, there's no evidence that it works in any versions in between those posted above. No, this has not worked in a previous version to my knowledge.
Thank you in advance for your help.
The text was updated successfully, but these errors were encountered:
dvdzkwsk
changed the title
_updateRenderedComponent Error if Rendered Child Components Repeatedly Throw
_updateRenderedComponent Error When Rendered Child Components Repeatedly Throw
Apr 24, 2017
Closing since I now realize this has been reported and the React team is aware of it. Would have appreciated a link to spare me the rabbit hole, so in case others stumble upon this:
Apologies in advance if this has already been reported. I did my best to thoroughly search through existing issues before posting this, but could not find something this specific. I'd be happy to move/close this as needed. This is (hopefully) more nuanced than the issue about "my render method threw and React blew up, why?" that I mostly encountered.
Do you want to request a feature or report a bug?
Bug.
Minimal Test Cases
Uncaught TypeError: Cannot read property '_currentElement' of null
Uncaught TypeError: Cannot read property 'getNativeNode' of null
What is the current behavior?
If a child component throws in its
render
method, and attempts to be rendered more than once, React throws an uncaught error inside of its internal_updateRenderedComponent
method. Depending on the context, this error is either:Uncaught TypeError: Cannot read property 'getNativeNode' of null
Uncaught TypeError: Cannot read property '_currentElement' of null
Let's say we have a problematic component
A
. WhenA
renders it throws a runtime error.A
. During the first render, we see the error thatA
threw while rendering. This is as expected and is a userland error.A
, we get a different exception. This is where we seeUncaught TypeError: Cannot read property 'getNativeNode' of null
from React (or the one referring to_currentElement
).The difference between exceptions #1 (
getNativeNode
) and #2 (_currentElement
) is that #1 happens when componentA
is the same between each render; #2 happens when componentA
is swapped in the second render with another component that also happens to throw while rendering. The latter is more likely as we move from a loaded -> error handler view, where the error view may unfortunately also throw.Why would you render a broken twice? Well, consider something as simple as this:
This is what led to the discovery of this bug. The promise handling here is technically incorrect, since what we really meant was to use
.then(onSuccess, onFailure)
so that we didn't implicitly catch synchronous render errors caused by thesetState
call in theonSuccess
callback. However, I do believe there are valid scenarios where this occurs, such as when manually handling a render error, but where the recovering component rendered in its place also (unfortunately) throws and consequently leads to this untraceable error.What is the expected behavior?
React should not blow up with this internal/untraceable error on the second render. I'm not even sure if this is possible, but at a minimum I'd like to better understand why this occurs.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Browser: Google Chrome Version 58.0.3029.81 (64-bit)
React:
Those are just the versions I've tested, there's no evidence that it works in any versions in between those posted above. No, this has not worked in a previous version to my knowledge.
Thank you in advance for your help.
The text was updated successfully, but these errors were encountered: