Modern JavaScript frameworks, and ReactJS are not an exception, usually require exclusive access to the DOM and they really don’t like it to be changed by someone without their knowledge. The problem is that there are a huge number of third-party libraries (for example, jQuery plug-ins) that need something in their subtree-controlled something to drop, unprotect, move to another place, etc. Usually in such cases we see something similar in the console:

Fortunately, this problem is quite easily and quickly solved. In this post I will try to present the solution step by step, but if you are not interested or are in a hurry, just go down to the link to the gist with the ready solution. So, let's begin.
Who is guilty?
Suppose we want to use in our ReactJS project some kind of mega-cool text editor, like AceEditor or TinyMCE. This plugin takes the <textarea /> element and turns it into a <div contenteditable /> element with a toolbar and a highlat, and it might look like this:
')
function textarea2editor(parent){ var $parent= jQuery(parent); var $editor = jQuery('<div contenteditable/>'); $editor.css('background', "#333"); $editor.css("color", "#efefef"); $parent.find('textarea').replaceWith($editor); return { setText: function (text){ $editor.html(text); }, } }
Suppose we have a ReactJS application that displays Unix commands at a specified interval:
var App = React.createClass({ render: function() { return ( <div> <textarea value={this.props.contents}/> </div> ) } }); var Component = React.render(<App contents="#./configure" />, document.body); setTimeout(function(){ Component.setProps({ contents: "#/.configure\n#make" }); }, 1000); setTimeout(function(){ Component.setProps({ contents: "#/.configure\n#make\n#make install" }); }, 2000);
We would like, of course, to use the above-described plugin for the command's highlight, for this, as usual, we first add the componentDidUpdate method to our component, which will initialize the editor:
componentDidMount: function(){ this.editor = textarea2editor(this.getDOMNode()); this.editor.setText(this.props.contents); }
As well as the componendDidUpdate method, which will update the contents of the <div contenteditable /> with each update of the component:
componentDidUpdate: function(){ this.editor.setText(this.props.contents); }
And here we have the next
fiddle .
When we launch it, we will see that only the first command appears in the “terminal”, but not the rest. And if we open the console, we will see why this happens:

The point, of course, is that our “editor” replaced <textarea /> with <div contenteditable /> without React's knowledge, and now React is confused, he has <textarea /> in his virtual house, but he doesn’t , and it is not clear how in such conditions to do diff and update the page.
And what to do?
Fortunately, the solution is very simple, but it did not come to me at once. I was inspired to this decision by the experience of communicating with AngularJS, where there is the ngNonBindable directive, which says to Angoulard:

I wondered if there was anything like that in React. The documentation does not (directly) say about this, but it says about the method shouldComponentUpdate, which returns a boolean value, and if it is false, then React will not update not only the component, but its entire subtree. That is, he simply will not call the methods componentWillUpdate, componentWillReceiveProps, render, etc. This method is proposed as an optimization tool, but wait, and if it does not cause render, the subtree of the components in the virtual DOM does not change, it means that for this virtual subtree, the diff and the corresponding real DOM are not needed in principle, does this mean that With this “optimization” method, can the React be made to ignore certain parts of the DOM-a subject to it? It turns out you can, but if we add to our component:
shouldComponentUpdate: function (){ return false; }
then the errors will disappear, but our “terminal” will not be updated anyway. Actually, we need to force React to ignore only the <textarea />, not the entire component, do we really have to write RenderOnceTextarea and so whenever we want to use the component from React.DOM?
In fact, there is a better solution - to write to the ReactIgnore component, which always returns its children, and always returns the false to shouldComponentUpdate:
var ReactIgnore = React.createClass({ displayName: 'ReactIgnore', shouldComponentUpdate: function(){ return false; }, render: function (){ return React.Children.only(this.props.children); } });
Here is a working
fiddle .
tl; dr aka gist link
I copied ReactIgnore from my project and laid it out as a
gist (Achtung, ES6 Harmony), use it on health.