所以,我正在阅读ReactJS Getting Started guide。我遇到了我修改过的this component (JSFiddle)。
如您所见,当您更改SearchBar组件时,它会更改父FilterableProductTable的状态。然后调用父#render方法,重新创建SearchBar,并再次调用SearchBar#render方法。
/** @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);
然而。如果我通过浏览器检查器手动编辑SearchBar组件的DOM,当我在文本框中键入内容时,SearchBar会被呈现(您可以看到DOM上的数据属性更改),但手动修改的DOM不会# 39;改变,这意味着实际上并不是渲染所有东西,只是改变的东西。
那么,它是如何做到的呢?在幕后进行脏检查吗? HTML上的差异?
答案 0 :(得分:4)
我找到了答案。 ReactJS使用Diff algorithm with the virtual DOM,它显然足够快速和智能。它还允许您在组件上设置shouldComponentUpdate
方法,告诉它在某些情况下不应该重新渲染。