React多组件布局

Published by xiaosixi on

 本文要实现下图的功能,我们这里数据用静态的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"}
];

首先把图分成几部分:

分别描述(定义的名称在下面对应小组件的名称):

  1. FilterableProductTable (orange): 总的组件

  2. SearchBar (blue): 用户输入交互区

  3. ProductTable (green): 数据展示区

  4. ProductCategoryRow (turquoise): 分类

  5. 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

Categories: React

xiaosixi

本人IT码农一枚,从事java企业级应用开发,目前就职于深圳某某公司,热衷于对技术的研究和热爱。本网站主要记录生活、工作上所发生所看的,可能大多来自互联网,如有版权问题,请联系,我会及时处理。

0 Comments

发表评论

电子邮件地址不会被公开。 必填项已用*标注