我从搜索结果返回的数据有下列: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>
);
}
}
猜对了,您想创建多个列表,而每个列表显示另一个"AddInfo"的项目。
首先,我建议将任务分为三个部分(而不是两个):第一个组件是列表文章,它将是列表项,第二个是组件列表 ->,它将接收您要显示的列表(在它们被过滤后),最后一个组件将是ListContainer ->这个组件将包含多个列表(与AddInfo的选项一样多)。
然后,在ListContainer中,您可以遍历所有唯一的AddInfo,并为每个选项创建List组件 - 仅传递过滤的项目:
列表文章.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;
列表.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")} />
)
)
}
}
列表容器.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} />
希望它对:)有所帮助
我会从你的List
类中返回这样的东西(我尝试在代码内的注释中解释我的思维过程):
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++
行替换为自动来自map
函数中第二个参数的i
索引(请参阅我的array.map((article, i) => ...
版本) - 如果您还没有看到数组解构之类的东西(例如:
.map(([type, array]) => ...)
)让我知道,我可以解释一下。这是一件非常时髦的事情,你可以做一些事情来保存一些台词。 - 我的第一步是弄清楚如何创建一个对象容器,该容器保存基于
AddInfo
的排序数据 - 这就是为什么我的// first
评论在技术上是在// second
评论之后。希望这是有道理的。 - 如果您有疑问或是否有打字机破坏了我的代码,请告诉我。我没有明显测试它,因为我没有你的反应代码/变量。