Sponsored Content
Skip to content

TypeError: Cannot read property '_currentElement' of null #4026

Closed

Description

@korakon

From maintainers: if you have this problem, please see the explanation in #6895 (comment).

Test case: jsFiddle

The error is in this function, internalInstance is null.

  /**
   * Releases any resources allocated by `mountComponent`.
   *
   * @final
   * @internal
   */

  unmountComponent: function(internalInstance) {
    ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
    internalInstance.unmountComponent();
  }

I managed to "fix" the bug by simply checking if internal state is not null but that requires modifying react.
Other mentions of this bug are listed below.

Activity

  1. syranide commented on Jun 4, 2015

    @syranide
    Contributor

    Some invariant violations leaves React in an unstable state at the moment so this is to be expected. AFAIK this is partly because catching and re-throwing errors is a crapshoot in many browsers and may also have significant performance impact on hot code-paths.

  2. korakon commented on Jun 4, 2015

    @korakon
    Author

    Some invariant violations leaves React in an unstable state at the moment so this is to be expected ...
    AFAIK this is partly because catching and re-throwing errors is a crapshoot in many browsers

    I am rethrowing the errors in the test case because it is easier to demonstrate that way, in an application I am developing, the error happens even when I am not re-throwing any errors, Here is an example.

    The function I am using is something like this, it simply switches pages,
    go(UserPage({user: {name: 'k'}) or shows an error page if an error happened.

    function go(page) {
        try {
             React.render(App(null, page), mount);
        catch (e) {
             React.render(App(null, ErrorPage({error: e})), mount);
        }
    }

    Test case

    Is there any way to manually clear the state besides removing and reinserting the dom element?
    I tried React.unmountComponentAtNode() but it throws the same error.

  3. JohnyDays commented on Jun 4, 2015

    @JohnyDays

    Perhaps have a higher level component AppWrapper, that contains that state? or pass page/ErrorPage as props, and do setProps on App (your top-level component)

  4. syranide commented on Jun 4, 2015

    @syranide
    Contributor

    @korakon It doesn't matter if you rethrow errors, my intended point was that React can internally catch and rethrow errors to avoid the internal state breaking (completely at least) but doesn't because there are undesirable side-effects in many browsers currently.

    AFAIK there is no clean way out of an invariation violation once it has happened. If you have a particularily vulnerable piece of code then wrap that in a try-catch, not the calls to React.

  5. korakon commented on Jun 4, 2015

    @korakon
    Author

    @JohnyDays
    Thank you, I will be using this.

    @syranide
    Yeah, I get your point know, Thank you.

  6. blairanderson commented on Oct 22, 2015

    @blairanderson

    I am seeing this quite a bit, but very little headway towards finding the root cause.

    on my local environment i can reproduce by adding an undefined variable into a function that changes the state of a component.

    it throws as undefined, then all other attempts to render on the parent node fail with TypeError: Cannot read property '_currentElement' of null...

    Is there a cool way to track stuff like this, given a giant component with a massive combinations of child components and states?

  7. JohnyDays commented on Oct 22, 2015

    @JohnyDays

    This usually happens if you interrupt react's rendering cycle with an exception, you should take care not to do so, and you can usually catch them easily during dev. I have never had this happen in prod, so perhaps it's related to some dev-only cycle

  8. blairanderson commented on Oct 22, 2015

    @blairanderson

    @JohnyDays that makes sense.

    Is there a way to force an unmount? I can't find any part of the api to do this.

    Current solution is a try/catch around render(which sometimes throws while unmounting) then in catch replacing the element with a new one and rendering on the new element.

    I'd like to have componentWillUnmount run for the components being unmounted(with force) and all its children before i remove the reference.

    Can you think of any way to do this?

  9. jordancardwell commented on Nov 4, 2015

    @jordancardwell

    @blairanderson FWIW, I recently found some sneaky regressions after migrating an app from 0.13 to 0.14.

    After a lot of headache, I realized someone was mutating child props like

    this.props.children[0].props.className = 'hidden'
    

    This was hard to pinpoint, since the error didn't really point in any particular direction.

    It was, however, easily fixed, once I found it by replacing with

    var childrenWithNewProps = React.Children.map(this.props.children, function(child) {
      return React.cloneElement(child, { className: 'hidden' });
    });
    

    hopefully someone will find this helpful moving forward

  10. jimfb commented on Nov 4, 2015

    @jimfb
    Contributor

    @jordancardwell You should have gotten a warning for that in dev mode with React 0.13. We try to warn in the previous version whenever making breaking changes, such that if you fix all your warnings then the migration to the next version will go smoothly.

  11. jordancardwell commented on Nov 9, 2015

    @jordancardwell

    @jimfb yeah, that's is actually something react is really good at, and has made migrating to new versions pretty pleasant for the most part.

    I definitely missed a deep dark corner of the app when clearing up warnings before this update.

    That said, for cases when this happens, a more specific/descriptive error could be really helpful.

    Maybe (optionally) logging a dump describing the unexpected variation, when in dev mode(?).. anything to prevent a dev from iterating through rounds of commenting out components and chunks of render methods to pinpoint where the 'bad thing' happened, and what flavor of 'bad thing' it was. (in my case, directly mutating child props)

    Being familiar with React internals, you probably have a better idea of how feasible this is.

  12. jimfb commented on Nov 9, 2015

    @jimfb
    Contributor

    @jordancardwell We did exactly that in 0.13.

    Example text of error message:

    Warning: Don't set .props.myFooProp of the React component <FooComponent />. Instead, specify the correct value when initially creating the element or use React.cloneElement to make a new element with updated props.

  13. jordancardwell commented on Nov 9, 2015

    @jordancardwell

    @jimfb Right, I'm familiar with the warning messages about deprecations and breaking changes in future versions in React, and as I stated in the previous comment:

    I definitely missed a deep dark corner of the app when clearing up warnings before this update.

    I missed this particular warning in one area of our app before updating, but had corrected for the rest of the warnings that were thrown.

    I was referring to the error message when something in your app causes an invariant violation in the current version (whatever it may be at the time). Some contextual information to point you in the right direction would be pretty valuable for anyone finding themselves in my situation.

    React has always been extremely helpful with error messages and documentation around common errors. My comment about the feasibility of providing more information around invariant violations is to help in the situation where you've unwittingly done something stupid to cause it or failed to update something before a migration.

  14. jordancardwell commented on Nov 9, 2015

    @jordancardwell

    So I supposed your point was that it's clearly feasible to do.. would it make sense to leave those descriptive messages in when people shoot foot-guns in dev mode.

    So though it can still be a breaking change, the dev can get some helpful info.. you did this and it blew things up, we stopped allowing this in 0.13. get with the program.

  15. 4 remaining items

  16. Danita commented on Mar 3, 2016

    @Danita

    I have a project set up with Webpack hot module reload. I can trigger this error (Uncaught TypeError: Cannot read property '_currentElement' of null in ReactReconciler.js) if I have some invalid code in a component, which triggers a expected exception, then correcting the invalid code, which causes the hot module reload, which seems to trigger this TypeError.

    Summing up, in my case it's occurring on every hot module reload which results from correcting a javascript error.

  17. rossPatton commented on Apr 3, 2016

    @rossPatton

    i agree with @tcurdt on these vague errors killing productivity. i know this issue is closed and piling on prolly doesn't help much, but i've had massive problems trying to update the website at my work from react 12 (i know) to react 13, which in theory shouldn't be hard to do. but this one error is causing me a lot of grief, because it's not clear why it's happening, where it's happening, what's causing it, etc

  18. blairanderson commented on Apr 3, 2016

    @blairanderson

    @rossPatton in chrome you can activate pause on exception and track down which component path is breaking.

    Almost always from rendering code throwing an error and preventing the render from completing.

  19. jameswomack commented on Apr 9, 2016

    @jameswomack

    @Danita Same here. Have you discovered a way to circumvent this error by forcing a refresh of the Webpack bundle?

  20. gaearon commented on Apr 10, 2016

    @gaearon
    Collaborator

    This error message usually just mean that render() of some component threw during the initial mount. If you look above this error message and ignore it, you will see the real error message.

  21. jameswomack commented on Apr 10, 2016

    @jameswomack

    My problem was that I had two React transforms, and the transform before
    catch-errors was preventing catch-errors from working. Once I incorporated
    error catching into the first transform, I was able to see the exact error
    and HMR continued effectively.

    On Sunday, April 10, 2016, Dan Abramov notifications@github.com wrote:

    This error message usually just mean that render() of some component
    threw during the initial mount. If you look above this error message
    and ignore it, you will see the real error message.

    —
    You are receiving this because you commented.
    Reply to this email directly or view it on GitHub
    #4026 (comment)

    James J. Womack
    Senior Software Engineer/Architect
    Netflix

  22. asadighi commented on May 31, 2016

    @asadighi

    React team can learn a thing or two from Angular team about handling/messaging these kind of errors

  23. art-in commented on Jun 20, 2016

    @art-in

    @gaearon

    This error message usually just mean that render() of some component threw during the initial mount.

    Ok. But sad thing is that if you try to replace component that throws error in render() with another component (like, error message component) - "_currentElement" error will be frown again anyway.

    My case:
    I have global error handler set through window.onerror.
    On window.onerror I'm setting ErrorScreen as current (which does not throw error in render()).

    Now, my BadComponent throws error in render().
    It is caught in window.onerror, ErrorScreen set. But react still re-throws "_currentElement"-error.
    What I got is infinite error loop.

    Why "_currentElement"-error is thrown if I'm not trying to render BadComponent any more?

  24. gaearon commented on Jun 20, 2016

    @gaearon
    Collaborator

    @artin-phares

    React currently cannot recover from an error inside render. Even a custom onerror handler won’t help here—the library’s internal state becomes corrupted because of the error, and it can’t render “something else”. Until error boundaries are fully supported (you can track #2461), I think your best is to remove the container DOM element and create a new one where you’d render <ErrorScreen>. Not sure whether this would work, but there’s higher chance it will than if you just ReactDOM.render() into an existing container that’s messed up.

  25. art-in commented on Jun 20, 2016

    @art-in

    @gaearon Ok. Looks like highly known issue. Thanks.

  26. blairanderson commented on Oct 5, 2016

    @blairanderson
  27. oklas commented on Feb 21, 2017

    @oklas

    What is exactly solved is meant by that:

    this is being solved in v15 with unstable_handleError()

    I have react 5.14.1 I only add to render() method the next:

    (undefined).x
    

    and see

    Uncaught TypeError: Cannot read property '_currentElement' of null

  28. gaearon commented on Feb 21, 2017

    @gaearon
    Collaborator

    I posted an explanation about this problem here: #6895 (comment).
    I am locking this thread for the same reasons I locked #6895.

    I hope the explanation helps!

  29. locked and limited conversation to collaborators on Feb 21, 2017
  30. gaearon commented on Jul 27, 2017

    @gaearon
    Collaborator

    A small update on this. We just released React 16 beta which shouldn’t emit cryptic errors like this one. Even if the application code swallows an error, React 16 will still print it to the console. It might be too early for you to try React 16 (since ecosystem is still preparing for it), but this error should never occur in the future after you switch to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions