React多组件布局
本文要实现下图的功能,我们这里数据用静态的json数据分别如下:
JSON数据:
[
{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"}
];
首先把图分成几部分:

分别描述(定义的名称在下面对应小组件的名称):
-
FilterableProductTable (orange): 总的组件
-
SearchBar (blue): 用户输入交互区
-
ProductTable (green): 数据展示区
-
ProductCategoryRow (turquoise): 分类
-
ProductRow (red): 产品列表
代码如下:
ProductCategoryRow
var ProductCategoryRow = React.createClass({
render: function() {
return (<tr><th colSpan="2">{this.props.category}</th></tr>);
}
});
ProductRow
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>
);
}
});
ProductTable
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>
);
}
});
SearchBar
var SearchBar = React.createClass({
handleChange:function(){
this.props.onUserInput(
this.refs.filterTextInput.value,
this.refs.inStockOnlyInput.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>
);
}
});
FilterableProductTable
var FilterableProductTable = React.createClass({
handleUserInput:function(filterText,inStockOnly){
this.setState({
filterText:filterText,
inStockOnly:inStockOnly
});
},
getInitialState: function() {
return {
filterText: '',
inStockOnly: false
};
},
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>
);
}
});
JSON数据:
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'}
];
写DOM数据
ReactDOM.render(
<FilterableProductTable products={PRODUCTS} />,
document.getElementById('container')
);
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Basic Example</title>
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap-theme.min.css">
<style type="text/css">
body{
padding:20px
}
</style>
</head>
<body>
<div id="container">
</div>
<script src="node_modules/react/dist/react.js"></script>
<script src="node_modules/react-dom/dist/react-dom.js"></script>
<script src="node_modules/browser/browser.min.js"></script>
<script src="node_modules/react-bootstrap/dist/react-bootstrap.min.js"></script>
</body>
</html>
以上的例子有几点:
1、父组件既可以传属性值,也可以传回调方法,用来获取子组件值来更改属性
2、state、props的应用
初学者做为记录,原文链接:https://facebook.github.io/react/docs/thinking-in-react.html
0 Comments