【问题标题】:Filter search results react过滤搜索结果反应
【发布时间】:2019-06-06 16:04:23
【问题描述】:

我从搜索结果返回的数据有列:enTitle、Image、url、enDescription、HasLandingPage、AddInfo。

我想通过 AddInfo 过滤搜索结果以显示在不同的列表中。以后如果能加个按钮就更好了。

渲染数据:

const ListArticle = (props) =>{
    return (
        <div className="card">
            <div className="search-img-lft">
                <a href={props.link} target="_blank">
                    <img src={props.image} alt="" />
                </a>
            </div>
            <div className="search-imgcont-rgt">
                <a href={props.link} target="_blank">
                    <h3>
                        {props.title}
                        {props.kind} // just to see if kind works
                    </h3>
                    <p>{props.desc}</p>
                </a>
                <a href={props.link} target="_blank" className="default-link">{props.link}</a>
            </div>
        </div>
    );
}

列表类:(忽略它们用于分页的 i、brac 和 lim)

    class List extends React.Component {
        render(){
            const liArt =[];
            const searchText = this.props.searchText.toLowerCase().replace(/[^a-z0-9]/g, '');
            var i = 0;
            const brac = this.props.start;
            const lim = brac + this.props.qtyPerPage;
//the filter below works for resources but I want all to be filtered and show in the list in previous code snippet
                this.props.list.filter(u=>u.AddInfo == "resource").map((article)=>{
                        var artText = (article.enTitle + " " + article.URL + " " + article.enDescription + " " + article.AddInfo).toLowerCase().replace(/[^a-z0-9]/g, '');
                        if(artText.indexOf(searchText)===-1){
                            return;
                        }
                        i++;
                        if(brac<i && i<lim){
                            liArt.push(
                                    <ListArticle key={article.Image+article.URL} 
                                        title={article.enTitle}
                                        image={article.Image+"?h=100&mode=crop&scale=down"}
                                        link={JSON.stringify(article.HasLandingPage).toUpperCase()=="TRUE" ? "/en/"+article.URL : "/" + article.URL}
                                        desc={article.enDescription}
                                        kind={article.AddInfo.includes("SKU") ? " Product" : (article.AddInfo.includes("resource") ? " Resource" : " Page")} />
                            );//push
                        } //limit check  
                });//map
            return (
                <div className="search-page-listbox">
                    {liArt}
                </div>
                );
   }
}

【问题讨论】:

  • 您能否解释一下您遇到了什么错误或问题是什么?或者以某种方式将您的代码放入演示中,以便我们查看问题?
  • 没有错误我只是不知道如何过滤结果。在第二个 sn-p 中,我使用一个条件(AddInfo == "resource")进行过滤,它可以工作。如果我删除该过滤器,它将显示所有搜索结果。但我希望根据 AddInfo 分离数据。

标签: html reactjs


【解决方案1】:

如果我没听错,您想创建多个列表,而每个列表显示另一个“AddInfo”的项目。

首先,我建议将您的任务分成三个部分(而不是两个): 第一个组件是 ListArticle,它将是列表项, 其次是组件 List -> 它将接收您要显示的列表(在它们被过滤之后), 最后一个组件将是 ListContainer -> 这个组件将包含多个列表(与 AddInfo 的选项一样多)。

然后,在 ListContainer 中,您可以检查所有唯一的 AddInfo,并为每个选项创建 List 组件 - 仅传递过滤的项目:

ListArticle.js

import React from 'react';

const ListArticle = (props) =>{
    return (
        <div className="card">
            <div className="search-img-lft">
                <a href={props.link} target="_blank">
                    <img src={props.image} alt="" />
                </a>
            </div>
            <div className="search-imgcont-rgt">
                <a href={props.link} target="_blank">
                    <h3>
                        {props.title}
                        {props.kind} // just to see if kind works
                    </h3>
                    <p>{props.desc}</p>
                </a>
                <a href={props.link} target="_blank" className="default-link">{props.link}</a>
            </div>
        </div>
    );
}

export default ListArticle;

List.js

import React from 'react';
import ListArticle from './ListArticle';

export default class List extends React.Component {
    render() {
        return (
            this.props.list.map(article => <ListArticle key={article.Image + article.URL}
                title={article.enTitle}
                image={article.Image + "?h=100&mode=crop&scale=down"}
                link={JSON.stringify(article.HasLandingPage).toUpperCase() == "TRUE" ? "/en/" + article.URL : "/" + article.URL}
                desc={article.enDescription}
                kind={article.AddInfo.includes("SKU") ? " Product" : (article.AddInfo.includes("resource") ? " Resource" : " Page")} />
            )
        )
    }
}

ListContainer.js

import React from 'react';
import List from './List';


class ListContainer extends React.Component {

    constructor(props){
        super(props);
    }

    render() {

        let lists = {};
        let searchText = this.props.searchText;
        if(this.props){
            let filteredList = this.props.list.filter(article=>(article.enTitle + " " + article.URL + " " + article.enDescription + " " + article.AddInfo).toLowerCase().replace(/[^a-z0-9]/g, '').indexOf(searchText)!==-1);
            filteredList && filteredList.forEach(u => {
                if(lists[u.AddInfo]===undefined) lists[u.AddInfo]=[];
                lists[u.AddInfo].push(u);
            });
        }

        return(
            Object.keys(lists).map(function(key, index) {
                return <List list={lists[key]} />
             })
        )
    }
}

export default ListContainer;

用法:

<ListContainer list={list} searchText={searchText} />

希望它有所帮助:)

【讨论】:

  • @EvikGhazarian 不客气。一般来说,总是建议让 React 组件尽可能简单:)
【解决方案2】:

我会从您的 List 课程中返回类似的内容(我尝试在代码中的 cmets 中解释我的思维过程):

return (<React.Fragment>
    {
        // second (kinda), I'd convert the inside generated collection (object) into an array
        // -> where the array elements are now ["AddInfo type", [array of elements with that type]] 
        Object.entries(
            // first, convert the list into an object, collecting each type of "AddInfo" into
            // -> a unique property, and storing all objects w/ that type in an array
            this.props.list.reduce((output, u) => {
                if (!output[u.AddInfo]) output[u.AddInfo] = [];
                output[u.AddInfo].push(u);
                return output
            }, {})
        )
        // third, I'd map the new array of ["AddInfo type", [array of elements with that type]] into 
        // -> the jsx output you want, like this:
        .map(([type, array]) => {
            return <div className="search-page-listbox">
                {array.map((article, i) => {
                    // ... everything inside your ".map((article...)" function can go here
                })}
            </div>
        })
    }
</React.Fragment>)

几点说明:

  1. 您可以将var i = 0i++ 行替换为i 索引,该索引自动来自map 函数中的第二个参数(请参阅我的array.map((article, i) =&gt; ... 版本)
  2. 如果您还没有看到像数组解构这样的东西(例如:.map(([type, array]) =&gt; ...)),请告诉我,我可以解释。节省一些台词是一件非常时髦的事情。
  3. 我的第一步是弄清楚如何创建一个对象容器来保存基于AddInfo 的排序数据——这就是为什么我的// first 评论在技术上位于// second 评论之后。希望这是有道理的。
  4. 如果您有任何问题或是否有 typeo 破坏了我的代码,请告诉我。因为我没有你的反应代码/变量,所以我显然没有测试它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-02
    • 2012-07-05
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多