文檔頁面地址:https://doc.react-china.org/docs/thinking-in-react.htmlhtml
該文檔只給了具體實現思路,下面是我實現的代碼。react
初學react,若是有寫的不規範的地方,望你們多多指正!git
FilterableProductTable (橙色): 包含了整個例子
SearchBar (藍色): 接受全部的用戶輸入
ProductTable (綠色): 根據用戶輸入過濾並展現數據集合
ProductCategoryRow (綠松石色): 展現每一個分類的標題
ProductRow (紅色): 用行來展現每一個產品
文檔中清楚的爲咱們劃分出了具體組件模塊,各個組件實現以下:github
App.jsdom
import React from 'react'; import ReactDOM from 'react-dom'; import FilterableProductTable from './FilterableProductTable' ReactDOM.render( <FilterableProductTable/>, document.getElementById('root') );
FilterableProductTable.js
import React from 'react' import SearchBar from './SearchBar' import ProductTable from './ProductTable' /* * 須要定義的state或值: *原產品列表 *用戶輸入的搜索文本 *複選框的值 * 須要根據以上值計算的值: *產品的篩選列表 */ const data=[ {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"} ]; class FilterableProductTable extends React.Component{ constructor(props){ super(props); this.state = { filterText: '', inStockOnly: true, list:data }; this.handleSearch=this.handleSearch.bind(this); this.handleCheckBox=this.handleCheckBox.bind(this); } handleSearch(keywods){ this.setState({ filterText:keywods }); } handleCheckBox(checkBoxStatus){ this.setState({ inStockOnly:checkBoxStatus }); } render(){ const filterText=this.state.filterText; const inStockOnly=this.state.inStockOnly; const list=this.state.list; return( <div> <SearchBar filterText={filterText} inStockOnly={inStockOnly} onSearch={this.handleSearch} list={list} onCheckBox={this.handleCheckBox}/> <ProductTable filterText={filterText} inStockOnly={inStockOnly} list={list} /> </div> ) } } export default FilterableProductTable
SearchBar.js:
this
import React from 'react' class SearchBar extends React.Component{ constructor(props){ super(props); this.handleChange=this.handleChange.bind(this); this.checkboxChange=this.checkboxChange.bind(this); } handleChange(e){ e.preventDefault(); let inputText=this.refs.inputText.value; this.props.onSearch(inputText); } checkboxChange(e){ // let checkboxStatus=this.refs.checkbox.checked; 經過ref獲取 let checkboxStatus=e.target.checked; //經過event.target事件獲取 this.props.onCheckBox(checkboxStatus); } render(){ return( <div> <input type="text" ref='inputText' value={this.props.filterText} onChange={this.handleChange} placeholder="輸入產品名稱"/> <div> <input type="checkbox" ref="checkbox" checked={this.props.inStockOnly} onChange={this.checkboxChange}/> 僅僅展現有庫存的商品 </div> </div> ) } } export default SearchBar
ProductTable.js:spa
import React from 'react' import ProductCategoryRow from './ProductCategoryRow' import ProductRow from './ProductRow' class ProductTable extends React.Component{ /* constructor(props){ super(props); }*/ render(){ let filterText=this.props.filterText; let inStockOnly=this.props.inStockOnly; let curCategory=""; return( <table> <thead> <tr style={{fontWeight:'bold'}}> <td>Name</td> <td>Price</td> </tr> </thead> {this.props.list.map((value,index) => { let listItemShow; if(value.name.toLowerCase().indexOf(filterText.toLowerCase())!==-1||filterText===''){ listItemShow=true; if(inStockOnly===true&&value.stocked===true){ listItemShow=true; }else if(inStockOnly===true&&value.stocked===false){ listItemShow=false; } }else{ listItemShow=false; } let categoryStatus=false; if(value.category===curCategory){ categoryStatus=false; }else{ categoryStatus=true; } curCategory=value.category; return ( <tbody key={index}> <ProductCategoryRow category={value.category} categoryStatus={categoryStatus}/> <ProductRow stocked={value.stocked} name={value.name} price={value.price} show={listItemShow}/> </tbody> ) }) } </table> ) } } export default ProductTable
ProductCategoryRow.js
import React from 'react' class ProductCategoryRow extends React.Component{ /*constructor(props){ super(props); }*/ render(){ let styleObj = { display : this.props.categoryStatus ? 'block':'none', fontWeight:"bold" }; return( <tr style={styleObj}> <td> {this.props.category} </td> </tr> ) } } export default ProductCategoryRow
ProductRow.jscode
import React from 'react' class ProductRow extends React.Component{ /*constructor(props){ super(props); }*/ render(){ let styleObj = { display : this.props.show ? 'block':'none', }; return ( <tr style={styleObj}> <td> {this.props.name} </td> <td> {this.props.price} </td> </tr> ) } } export default ProductRow
總結:react 的state要定義在幾個組件的公共父組件上,這裏定義在最外層的 FilterableProductTable.js 組件上,修改state 即setState也在定義state的組件上操做,全部修改的方法經過傳入子組件,子組件經過props得到該方法,把改變以後的值傳入父組件,即實現了父子組件數據的雙向傳遞。htm
github源文件:https://github.com/beileixinqing/react-doc-demo-searchblog