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