React 实例-深入理解
html:
<!DOCTYPE html>
<html>
<head>
<Meta charset='utf-8' />
<script src="https://fb.me/react-0.13.3.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
</head>
<body>
<script type="text/jsx">
// 分类
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>
);
}
});
// 产品列表
// 基于 state 过滤列表
var ProductTable = React.createClass({
render: function() {
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() {
// 输入筛选条件时 将输入加入 props
this.props.onUserInput(
this.refs.filterTextInput.getDOMNode().value,this.refs.inStockOnlyInput.getDOMNode().checked
);
},render: function() {
return (
<form>
<input type="text" placeholder="Search..." value={this.props.filterText} ref="filterTextInput" onChange={this.handleChange} />
<p>
<input type="checkBox" checked={this.props.inStockOnly} ref="inStockOnlyInput" onChange={this.handleChange} />
Only show products in stock
</p>
</form>
);
}
});
// 显示搜索结果
var FilterableProductTable = React.createClass({
// 设置 state 作为 props 传递给 SearchBar 和 ProductTable
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',name: 'Baseball'},price: '$29.99',stocked: false,name: 'Basketball'},{category: 'Electronics',price: '$99.99',name: 'iPod Touch'},price: '$399.99',name: 'iPhone 5'},price: '$199.99',name: 'Nexus 7'}
];
React.render(<FilterableProductTable products={PRODUCTS} />,document.body);
</script>
</body>
</html>