过滤搜索结果反应
Posted
技术标签:
【中文标题】过滤搜索结果反应【英文标题】: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 />
</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 分离数据。 【参考方案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 />
</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>)
几点说明:
-
您可以将
var i = 0
和i++
行替换为i
索引,该索引自动来自map
函数中的第二个参数(请参阅我的array.map((article, i) => ...
版本)
如果您还没有看到像数组解构这样的东西(例如:.map(([type, array]) => ...)
),请告诉我,我可以解释。节省一些台词是一件非常时髦的事情。
我的第一步是弄清楚如何创建一个对象容器来保存基于AddInfo
的排序数据——这就是为什么我的// first
评论在技术上位于// second
评论之后。希望这是有道理的。
如果您有任何问题或是否有 typeo 破坏了我的代码,请告诉我。因为我没有你的反应代码/变量,所以我显然没有测试它。
【讨论】:
以上是关于过滤搜索结果反应的主要内容,如果未能解决你的问题,请参考以下文章
R Shiny Reactive 值,dplyr 过滤器错误?