react文档demo实现输入展示搜索结果列表

文档页面地址:https://doc.react-china.org/docs/thinking-in-react.html

该文档只给了具体实现思路,下面是我实现的代码。

初学react,如果有写的不规范的地方,望大家多多指正!

FilterableProductTable (橙色): 包含了整个例子
SearchBar (蓝色): 接受所有的用户输入
ProductTable (绿色): 根据用户输入过滤并展示数据集合
ProductCategoryRow (绿松石色): 展示每个分类的标题
ProductRow (红色): 用行来展示每个产品

文档中清楚的为我们划分出了具体组件模块,各个组件实现如下:

App.js

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:

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:

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

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获得该方法,把改变之后的值传入父组件,即实现了父子组件数据的双向传递。

github源文件:https://github.com/beileixinqing/react-doc-demo-search

posted @ 2018-02-09 11:26  蓓蕾心晴  阅读(1738)  评论(0编辑  收藏  举报