Reputation: 3499
So, I was reading through the ReactJS Getting Started guide. And I came across this component (JSFiddle) that I modified.
As you can see, when you change the SearchBar component, it changes the state of the parent FilterableProductTable. And then the parent #render method gets called, and recreates the SearchBar, and calls the SearchBar#render method again.
/** @jsx React.DOM */
var ProductCategoryRow = React.createClass({
render: function() {
return (<tr><th colSpan="2">{this.props.category}</th></tr>);
}
});
var ProductRow = React.createClass({
render: function() {
var name = this.props.product.stocked ?
this.props.product.name :
<span style={{color: 'red'}}>
{this.props.product.name}
</span>;
return (
<tr>
<td>{name}</td>
<td>{this.props.product.price}</td>
</tr>
);
}
});
var ProductTable = React.createClass({
render: function() {
console.log(this.props);
var rows = [];
var lastCategory = null;
this.props.products.forEach(function(product) {
if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) {
return;
}
if (product.category !== lastCategory) {
rows.push(<ProductCategoryRow category={product.category} key={product.category} />);
}
rows.push(<ProductRow product={product} key={product.name} />);
lastCategory = product.category;
}.bind(this));
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
);
}
});
var SearchBar = React.createClass({
handleChange: function() {
this.props.onUserInput(
this.refs.filterTextInput.getDOMNode().value,
this.refs.inStockOnlyInput.getDOMNode().checked
);
},
render: function() {
console.log('This SearchBar#render is being called every time the state changes!');
return (
<form>
<input
type="text"
placeholder="Search..."
value={this.props.filterText}
ref="filterTextInput"
onChange={this.handleChange}
/><span data-something={this.props.filterText}>Edit this text manually with the DOM inspector. Type something on the text box. Look that the data-something property is re-rendered, but this text is kept the same</span>
<p>
<input
type="checkbox"
value={this.props.inStockOnly}
ref="inStockOnlyInput"
onChange={this.handleChange}
/>
Only show products in stock
</p>
</form>
);
}
});
var FilterableProductTable = React.createClass({
getInitialState: function() {
return {
filterText: '',
inStockOnly: false
};
},
handleUserInput: function(filterText, inStockOnly) {
this.setState({
filterText: filterText,
inStockOnly: inStockOnly
});
},
render: function() {
return (
<div>
<SearchBar
filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
onUserInput={this.handleUserInput}
/>
<ProductTable
products={this.props.products}
filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
/>
</div>
);
}
});
var PRODUCTS = [
{category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
{category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
{category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
{category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
{category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
{category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];
React.renderComponent(<FilterableProductTable products={PRODUCTS} />, document.body);
However. If I edit the DOM of the SearchBar component manually through the browser inspector, when I type something in the text box, the SearchBar gets rendered (you can see the data-something property change on the DOM), but the manually modified DOM doesn't change, so that means that is not actually rendering everything, just the things that changed.
So, how is it doing it? Does it do dirty checking behind the scenes? A diff on the HTML?
Upvotes: 1
Views: 598
Reputation: 3499
I found my answer. ReactJS uses a Diff algorithm with the virtual DOM, and it's apparently fast and smart enough. It also lets you set a shouldComponentUpdate
method on your component to tell it that it shouldn't re-render on some condition.
Upvotes: 4