---------------------可爱的分割线---------------------------------------
以下JS文件和CSS文件请自行替换,product.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":true,"name":"Basketball"},
  {"category":"Electronics Goods","price":"$99.99", "stocked":false,"name":"iPod Touch"},
  {"category":"Electronics Goods","price":"$399.99","stocked":true,"name":"iPhone 5"},
  {"category":"Electronics Goods","price":"$199.99","stocked":false,"name":"Nexus 7"},
  {"category":"PC Goods",         "price":"$39.99", "stocked":false,"name":"IBM x2005"},
  {"category":"PC Goods",         "price":"$19.99", "stocked":false,"name":"IBM x2008"}
]
---------------------可爱的分割线---------------------------------------
<!DOCTYPE html>
<html>
  <head>
    <script src="react-demos/build/react.js"></script>
    <script src="react-demos/build/react-dom.js"></script>
    <script src="react-demos/build/browser.min.js"></script>
    <script src="react-demos/build/jquery.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/showdown/0.3.1/showdown.min.js"></script>
    <link rel="stylesheet" href="react-demos/build/bootstrap.css" />
    <style>
      body{
        font-family:"microsoft yahei";
        padding:20px;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script type="text/babel">
      var Product = React.createClass({
        getInitialState:function(){
          return ({data:[],onlyStocked:false,filterWord:""})
        },
        componentDidMount:function(){
          $.ajax({
            url:this.props.url,
            dataType:"json",
            success:function(data){
              this.setState({data:data});
            }.bind(this),
            error:function(xhr,status,err){
              console.error(this.props.url,status,err.toString());
            }.bind(this)
          })
        },
        onlyStock:function(bool){
          this.setState({onlyStocked:bool});
        },
        handleFilter:function(word){
          this.setState({filterWord:word});
        },
        render:function(){
          return (
          <div>
          <SearchBox onlyStocked={this.onlyStock} sendFilter={this.handleFilter}/>
          <ProductList data={this.state.data} onlyStock={this.state.onlyStocked} filter={this.state.filterWord}/>
          </div>
          )
        }
      });
      var SearchBox = React.createClass({
        handleChange:function(e){
          this.props.onlyStocked(e.target.checked);
        },
        handleInput:function(e){
          this.props.sendFilter(e.target.value);
        },
        render:function(){
          return (
          <div>
            <p><input type="text" placeholder="Search..."  onChange={this.handleInput}/></p>
            <p><label><input type="checkbox" onChange={this.handleChange}/>Only show products in stock</label></p>
          </div>
          )
        }
      });
      var ProductList = React.createClass({
        render:function(){
          var nowCategory = "";
          var listDetails =[];
          var onlyStock = this.props.onlyStock;
          var filterWord = this.props.filter;
          this.props.data.map(function(value){
            if(value.category!==nowCategory){
              if(onlyStock){
                if(value.stocked){
                  listDetails.push(
                <CategoryTable product={value}/>
                )
                  listDetails.push(
                <ListTable product={value} filter={filterWord}/>
                )
                  nowCategory=value.category;
                }
              }else{
                listDetails.push(
              <CategoryTable product={value}/>
              )
                listDetails.push(
              <ListTable product={value} filter={filterWord}/>
              )
                nowCategory=value.category;
              }
              }
            else{
              if(onlyStock){
                if(value.stocked){
                  listDetails.push(
                <ListTable product={value} filter={filterWord}/>
                )
                }
              }else{
                listDetails.push(
              <ListTable product={value} filter={filterWord}/>
              )
              }
            }
          });
          return (
          <table>
          <thead>
          <tr>
          <th>name</th><th>Price</th>
          </tr>
          </thead>
          <tbody>
                  {listDetails}
          </tbody>
          </table>
          )
        }
      });
      var CategoryTable = React.createClass({
        render:function(){
          return (
          <tr>
          <td colspan="2"><b>{this.props.product.category}</b></td>
          </tr>
          )
        }
      });
      var ListTable = React.createClass({
        render:function(){
          if(this.props.filter){
           if(this.props.product.name.toLowerCase().indexOf(this.props.filter.toLowerCase())!==-1){
             return(
           <tr className={this.props.product.stocked?"":"text-danger"}><td>{this.props.product.name}</td><td>{this.props.product.price}</td></tr>
           )
           }else{
             return null;
           }
          }else{
            return(
          <tr className={this.props.product.stocked?"":"text-danger"}><td>{this.props.product.name}</td><td>{this.props.product.price}</td></tr>
          )
          }
        }
      });
      ReactDOM.render(<Product url="product.json"/>,document.getElementById("container"));
    </script>
  </body>
</html>