React搜索过滤功能

React Search filter function

本文关键字:功能 过滤 搜索 React      更新时间:2023-09-26

基本上,我的代码所做的是显示一个名称表列表,顶部有一个搜索栏,当您输入值时过滤列表。目前我的代码所遇到的问题是向DisplayTable组件添加if语句。我不希望它显示所有存储的数据而只显示用户在搜索栏{queryText}

中输入的数据

请忽略tableData变量

var InstantBox = React.createClass({
    doSearch:function(queryText){
        console.log(queryText)
        //get query result
        var queryResult=[];
        this.props.data.forEach(function(person){
            if(person.name.toLowerCase().indexOf(queryText)!=-1)
            queryResult.push(person);
        });
        this.setState({
            query:queryText,
            filteredData: queryResult
        })
    },
    getInitialState:function(){
        return{
            query:'',
            filteredData: this.props.data
        }
    },
    render:function(){
        return (
            <div className="InstantBox">
                <h2>Who is Richer?</h2>
                <SearchBox query={this.state.query} doSearch={this.doSearch}/>
                <DisplayTable data={this.state.filteredData}/>
            </div>
        );
    }
});
var SearchBox = React.createClass({
    doSearch:function(){
        var query=this.refs.searchInput.getDOMNode().value; // this is the search text
        this.props.doSearch(query);
    },
    render:function(){
        return <input className="searchbar-edit" type="text" ref="searchInput" placeholder="Search Name" value={this.props.query} onChange={this.doSearch}/>
    }
});
var DisplayTable = React.createClass({
      doSearch:function(queryText){
        console.log(queryText)
        //get query result
        var queryResult=[];
        this.props.data.forEach(function(person){
            if(person.name.toLowerCase().indexOf(queryText)!=-1)
            queryResult.push(person);
        });
        this.setState({
            query:queryText,
            filteredData: queryResult
        })
    },
    render:function(){
        //making the rows to display
        var rows=[];
        this.props.data.forEach(function(person) {
        rows.push(<tr><td>{person.image}</td></tr>)
        rows.push(<tr><td>{person.name}</td></tr>)
        });        
        //returning the table
        return(
             <table>
                <tbody>{rows}</tbody>
            </table>
        );
    }
});
var tableData=[
{
    name:'Paul mak',
    image: <img width="50" src="./images/profile_img.png"/>,
},
];
var dataSource=[
{
    name:'Paul mak',
    image: <img width="50" src="./images/profile_img.png"/>,
},
{
    name:'John Doe',
    image : '002'
},
{
    name:'Sachin Tendulkar',
    image : '003'
}];

React.render(
  <InstantBox data={dataSource}/>,
  document.getElementById('content1')
);

试试这样:

var InstantBox = React.createClass({
    doSearch:function(queryText){
        console.log(queryText)
        //get query result
        var queryResult=[];
        this.props.data.forEach(function(person){
            if(person.name.toLowerCase().indexOf(queryText)!=-1)
            queryResult.push(person);
        });
        this.setState({
            query:queryText,
            filteredData: queryResult
        })
    },
    getInitialState:function(){
        return{
            query:          '',
            filteredData:   undefined
        }
    },
    renderResults: function() {
        if (this.state.filteredData) {
            return (
                <DisplayTable data={this.state.filteredData}/>
            );
        }
    },
    render:function(){
        return (
            <div className="InstantBox">
                <h2>Who is Richer?</h2>
                <SearchBox query={this.state.query} doSearch={this.doSearch}/>
                {this.renderResults()}
            </div>
        );
    }
});

我从你的代码中改变的是,我将this.state.filteredData更改为未定义(实际上你可以完全删除它,但我认为这对你来说现在更清楚)在你的初始状态。这样,当你第一次渲染盒子,没有filteredData和你的<DisplayTable />不渲染。只要你从<SearchBox />运行doSearch回调,它就会填充filteredData并显示它。

要扩展这一点,您还可以检查this.state.query是否再次未定义或空白(例如:this.state.query.length),如果没有查询/没有结果,则再次从dom中删除<DisplayTable />

记住render函数仍然只是javascript。在JSX中用{}封装的任何内容都将被计算。我们可以在render函数中使用这个逻辑,并做一些类似var displayTable = <DisplayTable />;的事情,然后在返回的JSX中包括{displayTable},这将是相同的。我个人更喜欢将渲染逻辑拆分为不同的函数:)