Javascript 反应搜索过滤功能

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31872994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:19:19  来源:igfitidea点击:

React Search filter function

javascriptreactjs

提问by Priince Abalogu

Basically what my code does is display a table list of names with a search bar at the top that filters the list as you type in a value. The problem I am having with my code at the moment is adding an if statement to the DisplayTable component. I dont want it to display all the stored data but just display the ones that have been inputted by the user in the search bar {queryText}

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

Please Ignore the tableData variable

请忽略 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')
);

回答by Mike Driver

Try something like this:

尝试这样的事情:

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>
        );
    }
});

What I've changed from your code is I changed this.state.filteredDatato be undefined (in fact you could just remove it entirely, but I thought this was clearer for you right now) in your initial state. This way when you first render the box, there's no filteredDataand your <DisplayTable />doesn't render. As soon as you run your doSearchcallback from <SearchBox />it will populate filteredDataand display it.

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

To extend this you could also check when this.state.queryis undefined again or blank (eg with : this.state.query.length) to remove <DisplayTable />from the dom again if there is no query / no results.

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

Remember renderfunctions are still just javascript. Anything you wrap in {}inside JSX will be evaluated. We could have just had this logic inside the renderfunction and be doing something like var displayTable = <DisplayTable />;and then including {displayTable}in the returned JSX and it would have been the same. I personally just prefer splitting render logic up among different functions :)

请记住,render函数仍然只是 javascript。你在{}JSX 中包装的任何东西都会被评估。我们可以在render函数内部使用这个逻辑var displayTable = <DisplayTable />;,然后做一些类似的事情,然后将其包含{displayTable}在返回的 JSX 中,它会是一样的。我个人更喜欢在不同的功能之间拆分渲染逻辑:)