带有 Javascript 和 React 的过滤器按钮



您好!我希望在我正在进行的项目中得到一些帮助。我创建了一个过滤功能,这样当用户点击按钮时,他们可以根据项目类型过滤我的项目。

我能够得到";ALL";按钮工作,但其他按钮不工作。预期的输出是,当我点击按钮时,它会过滤掉其他项目,并保留与类别匹配的项目。然而,当前的输出是,当我点击按钮时,项目就会消失。

这是我的代码:

import React, {useState} from "react";
import ReactDOM from "react-dom";
import styles from "./projects.module.scss";
import cards from "./allData";

function Projects() {

const [state, setState] = useState(cards);
const handleBtns = (e) => {
let word = e.target.value;
function isCardActive() {
for(const card of cards) {
if (cards.category === "FEATURED") {
return true;
} else if (cards.category === "WEB APP") {
return true;
} else if (cards.category === "MOBLE APP"){
return true
}
} 
};
if(word === 'All') { 
setState(cards)
} else if(word === 'Featured') {
const filtered = cards.filter(isCardActive);
setState(filtered);
}  else if(word === 'webApp') {
const filtered = cards.filter(isCardActive);
setState(filtered);
} else if(word === 'mobileApp') {
const filtered = cards.filter(isCardActive);
setState(filtered);
}
}

return(
<div className={styles.projects} id="projectHash">
<section>
<h3>PROJECTS</h3>
</section>

<section id={styles.filterMain}>
<button className={`${styles.filterBox} ${styles.active}`} onClick={handleBtns} type="button" value="All"  >VIEW ALL</button> 
<button className={styles.filterBox} onClick={handleBtns} type="button" value="Featured"  >FEATURED</button>
<button className={styles.filterBox} onClick={handleBtns} type="button" value="webApp"  >WEB APP</button>
<button className={styles.filterBox} onClick={handleBtns} type="button" value="mobileApp" >MOBILE APP</button>  

</section>
<section>
{state.map((cards) => (
<div className={styles.projectcard} key={cards.id} >
<h4>Project Name: {cards.title} </h4>
<br/>
<h4>{cards.image}</h4>

</div>
))}
</section>

</div>
)
};
export default Projects;

这是包含数据数组的文件的代码

import card1 from "../../assets/card1.jpg";
import card2 from "../../assets/card2.jpg";
import card3 from "../../assets/card3.jpg";
import card4 from "../../assets/card4.jpg";
import card5 from "../../assets/card5.jpg";
import card6 from "../../assets/card6.jpg";
const cards = [
{
title: 'VICTORY FOLIO',
category: ['WEB APP', 'FEATURED'],
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card1,
id: 1
},
{
title: 'IN WHOLENESS PRACTICE',
category: 'WEB APP',
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card2,
id: 2
},
{
title: 'TRIBE HAIRCARE',
category: ['WEB APP', 'MOBILE APP', 'FEATURED'],
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card3,
id: 3
},
{
title: 'TRIBE SKINCARE',
category: ['WEB APP', 'MOBILE APP'],
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card4,
id: 4
},
{
title: 'BUG TRACKER',
category: 'WEB APP',
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card5,
id: 5
},
{
title: 'PATIENT PORTAL',
category: 'MOBILE APP',
description: 'Lorem ipsum dolro sit amt, consestcuer elit',
image: card6,
id: 6
}
];
export default cards;

所以这里面有很多事情让它不起作用,但基本上你的isCardActive什么都不做,因为它没有收到要比较的当前卡项目。

我在这里创建了一个沙箱,说明它应该如何工作,当过滤器(currentCard(更改时,使用useState和useEffect来过滤结果。我已经去掉了造型,但你可以很容易地把它加回来。

代码在这里:

const [cards, setCards] = useState(allCards);
const [currentCard, setCurrentCard] = useState("All");
const handleBtns = (e) => {
let word = e.target.value;
setCurrentCard(word);
};
useEffect(() => {
if (currentCard === "All") {
setCards(allCards);
} else {
const filtered = allCards.filter((card) => {
return (
card.category === currentCard || card.category.includes(currentCard)
);
});
setCards(filtered);
}
}, [currentCard]);
return (
<div className="App">
<div id="projectHash">
<section>
<h3>PROJECTS</h3>
</section>
<section>
<button onClick={handleBtns} type="button" value="All">
VIEW ALL
</button>
<button onClick={handleBtns} type="button" value="FEATURED">
FEATURED
</button>
<button onClick={handleBtns} type="button" value="WEB APP">
WEB APP
</button>
<button onClick={handleBtns} type="button" value="MOBILE APP">
MOBILE APP
</button>
</section>
<h3>Current: {currentCard}</h3>
<section>
{cards.map((card) => (
<div key={card.id}>
<h4>Project Name: {card.title} </h4>
</div>
))}
</section>
</div>
</div>
);

下面是一个使用useState钩子的沙箱解决方案:codesandbox

我会注意到:

  1. 比较字符串值时,请确保它们使用相同的格式/大写:
'Feature' === 'FEATURE' //false 
'FEATURE' === 'FEATURE' //true 
  1. 规范化对象中的数据。JavaScript是动态类型的,因此可以这样做:
card.category = 'string'
card.category = ['STRING']

确保数据类型相同,就不需要在筛选函数中进行额外的检查。

您可以使用Array.filter((方法,也可以更改输入值以匹配类别,因为它们在带有大写字母和之间空格的卡片中定义

const handleBtns = (e) => {
const word = e.target.value;
if (word === "All") setState(cards);
else {
const filteredCards = cards.filter(({ category }) => {
return category.includes(word);
});
setState(filteredCards);
}
};

最新更新