React: TypeError: Cannot read property 'replaceChild' of null

Created on 8 Jun 2016  Â·  14Comments  Â·  Source: facebook/react

From maintainers: if you have this problem, please see the explanation in https://github.com/facebook/react/issues/6895#issuecomment-281405036.

Do you want to request a _feature_ or report a _bug_?
Bug

What is the current behavior?
Error thrown when using react-dnd. See this report.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/reactjs/69z2wepo/).
I provided sample code in the linked ticket, but I can create a repo with a minimal demo if necessary.

What is the expected behavior?
Error not created?

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 15.0.1, Meteor 1.3.2.4, React DND 2.1.4

Most helpful comment

@brigand It's mostly an indication that the DOM has been modified outside of React's control (parent is null, so when replacing a child it tries to call replaceChild on null), start looking there.

All 14 comments

Try 15.1.0; the version you're using is a couple releases old, and I think we've had some potentially relevant bug fixes since then.

Also, a minimal repro (at least one that runs in a jsfiddle), ideally one that doesn't rely on third-party dependencies like react-dnd would be most helpful. Try reproducing whatever react-dnd is doing in userland until you have a minimal repro without dependencies.

I am having a similar issue.
When I try to render english content to my components, it works fine. But when I try to load hindi, I get this error: Uncaught(in promise) TypeError: Cannot read property 'replaceChild' of null DOMLazyTree.js:69.

I have set encoding and charset to UTF-8.

I am using react 15.1.0

@AnshulMalik

I’m afraid information is not enough to help you. A small example reproducing the issue would be most helpful.

My issue is resolved now, I was assuming a variable to be array, It was the case when the variable was undefined, so the component was having issues with rendering.

I'm getting the same error in 15.3.1. Any ideas on how I can narrow it down? Stack:

 TypeError: Cannot read property 'replaceChild' of null
    at Function.replaceChildWithTree (webpack:///./~/react/lib/DOMLazyTree.js?:70:21)
    at Object.dangerouslyReplaceNodeWithMarkup (webpack:///./~/react/lib/Danger.js?:42:19)
    at Object.dangerouslyReplaceNodeWithMarkup [as replaceNodeWithMarkup] (webpack:///./~/react/lib/DOMChildrenOperations.js?:122:12)
    at ReactCompositeComponentWrapper._replaceNodeWithMarkup (webpack:///./~/react/lib/ReactCompositeComponent.js?:781:31)
    at ReactCompositeComponentWrapper._updateRenderedComponent (webpack:///./~/react/lib/ReactCompositeComponent.js?:771:12)
    at ReactCompositeComponentWrapper._performComponentUpdate (webpack:///./~/react/lib/ReactCompositeComponent.js?:721:10)
    at ReactCompositeComponentWrapper.updateComponent (webpack:///./~/react/lib/ReactCompositeComponent.js?:642:12)
    at ReactCompositeComponentWrapper.receiveComponent (webpack:///./~/react/lib/ReactCompositeComponent.js?:544:10)
    at Object.receiveComponent (webpack:///./~/react/lib/ReactReconciler.js?:126:22)
    at ReactCompositeComponentWrapper._updateRenderedComponent (webpack:///./~/react/lib/ReactCompositeComponent.js?:751:23)
    at ReactCompositeComponentWrapper._performComponentUpdate (webpack:///./~/react/lib/ReactCompositeComponent.js?:721:10)
    at ReactCompositeComponentWrapper.updateComponent (webpack:///./~/react/lib/ReactCompositeComponent.js?:642:12)
    at ReactCompositeComponentWrapper.performUpdateIfNecessary (webpack:///./~/react/lib/ReactCompositeComponent.js?:558:12)
    at Object.performUpdateIfNecessary (webpack:///./~/react/lib/ReactReconciler.js?:158:22)
    at runBatchedUpdates (webpack:///./~/react/lib/ReactUpdates.js?:151:21)
    at ReactReconcileTransaction.perform (webpack:///./~/react/lib/Transaction.js?:138:20)

@brigand It's mostly an indication that the DOM has been modified outside of React's control (parent is null, so when replacing a child it tries to call replaceChild on null), start looking there.

This was the problem code. Component was undefined. There's no warning for React.createElement getting an undefined type for some reason, and this is a development build. I'm unable to reproduce in jsfiddle.

  render(){
    var Component = typeToComponent[this.props.type];
    return (
      <Box style={{color: 'white'}}>
        <Component data={this.props.data} />
      </Box>
    );
  }

The root cause in all cases appears to be that an exception has occurred in a component method, e.g. in render() but the exception was swallowed higher up. Because the exception is swallowed, you cannot see it in the console and identify the root cause. All you see is follow-up errors in React code that is already operating on inconsistent state.

Consider this innocuous example, which you can imagine as part of a login form rendered by a React component:

onLoginFormSubmit(e) {
        e.preventDefault();
        try {
            let {email, password} = this.state;
            login(email, password);
        } catch (e) {
            console.log(e.message);
        }
        return false;
}

The try/catch block is there to prevent the default onsubmit behavior. However, if login calls setState at some point and render() throws an exception, then all you'll get is unhelpful Cannot read property 'replaceChild' of null exceptions.

The solution in this particular case is to call login inside a setImmediate. More generally, all entry points into React like ReactDOM.render or setState should be called in a clean call stack, without try/catch blocks.

Does it make sense to modify setState() itself to defer all state changes with setImmediate?

I'm getting this bug using draft-js. Why you can't just wrap this code into if (oldNode.parentNode)?

As explained above, this would not fix the underlying problem, which is that there is a crash somewhere in your code. If you don't see the first (underlying) error then it is likely your code that is swallowing it. Check your catch handlers, especially in Promises, as people often misunderstand how to use them, and direct errors from React setState into catch blocks when React is already in an inconsistent state, without surfacing them.

It wouldn't help to add if (oldNode.parentNode) because this is just defensive programming that will break down somewhere later down the line, with even more cryptic errors. You need to fix errors in your code instead.

Future versions of React will hopefully avoid this problem and be more aggressive in "failing fast", as well as letting you catch errors in components. Until then, please find the errors in your components (e.g. you can use "break on all exceptions" in Chrome).

I have the same error in my code. I want to render a new component that I already imported an it is not render. [(https://github.com/alimek/react-native-tooltip-menu)] this is the component that I am trying to use.

Please read the above comment.

Simple way how to reproduce...
in render method
throw Error('h');

and you will get Uncaught (in promise) TypeError: Cannot read property 'replaceChild' of null
and not see what crashed

@gaearon looks like new handleError in 15.x is catching this

and you will get Uncaught (in promise) TypeError: Cannot read property 'replaceChild' of null
and not see what crashed

Again, as I explained above this means your code (or some dependencies you are using) is swallowing the original error. You can verify this by enabling “break on caught exceptions” in the debugger.

I’m closing this because React 16 (just released) surfaces the original error even if your code accidentally swallows it. Hopefully this will help people. This particular error shouldn’t happen anymore either.

Was this page helpful?
0 / 5 - 0 ratings