I have gone through the Learn React.js (without JSX) series by James Nelson. The series introduces a form implemented with React and shows that the input fields are effectively read-only and then proceed to explain how to properly change the values. This is not a question on how to do so. Rather, I would like to understand how React prevents the values from changing.
The below code (also in jsfiddle) is a SSCCE:
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
</head>
<body>
<div>
<h3>simple HTML form (no ReactJS)</h3>
<form>
<input type='text' value placeholder='please enter your name'>
</form>
</div>
<div id='react-app'>
<script type='text/javascript'>
const rce = React.createElement.bind(React);
const rcc = React.createClass.bind(React);
const ContactForm = rcc({
propTypes: {
value: React.PropTypes.object.isRequired,
},
render: function() {
return rce('form', {}
, rce('input', {type: 'text'
, placeholder: 'please enter your name'
, value: this.props.value.name
, onInput: function(se) {
console.log(se.target.value);
}}))}
, componentWillMount : function () {console.log('componentWillMount');}
, componentDidMount : function () {console.log('componentDidMount');}
, componentWillReceiveProps: function () {console.log('componentWillReceiveProps');}
, shouldComponentUpdate : function () {console.log('shouldComponentUpdate');}
, componentWillUpdate : function () {console.log('componentWillUpdate');}
, componentDidUpdate : function () {console.log('componentDidUpdate');}
, componentWillUnmount : function () {console.log('componentWillUnmount');}
});
const ContactView = rcc({
propTypes: {
newContact: React.PropTypes.object.isRequired,
}
,render: function () {
console.log('render called');
return rce('div', {}
, rce('h3', {}, 'why doesn\'t the input field value change?')
, rce(ContactForm, {
value: this.props.newContact
}))
}
});
var reactApp = rce(ContactView, {newContact: {name: ''}});
ReactDOM.render(reactApp, document.getElementById('react-app'));
</script>
</body>
</html>
The above code produces two html forms: one created with simple HTML, the other with ReactJS. The elements rendered are identical:
For the simple HTML form:
For the HTML form created with ReactJS:
I am logging messages on the console for every component lifecycle method being called. The only ones that appear to be called are render
, componentWillMount
and componentDidMount
(and only at the beginning). When keystrokes are entered in the input text field, no subsequent life cycle methods are called.
So my question is: given that no additional lifecycle methods are called, how does ReactJS manage to prevent the input field value from changing given that its DOM representation is identical to that of a plain HTML form input field (in which the value displayed in my browser when I type into the input field does indeed change)?