使用 Javascript 和 React 的过滤按钮

Filter button with Javascript & React

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

我能够使“全部”按钮起作用,但其他按钮不起作用。 预期的输出是当我单击按钮时它会过滤掉其他项目并保留与类别匹配的项目。 然而,当前的输出是当我点击按钮时,项目消失了。

这是我的代码:

    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 什么都不做,因为它没有收到当前的卡片项目来进行比较。

我已经创建了一个沙盒 here 来说明它应该如何工作,使用 useState 和 useEffect 在过滤器 (currentCard) 更改时过滤结果。我删除了样式,但您可以很容易地将其添加回来。

代码在这里:

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

您可以使用 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);
}

};

这是一个沙箱,我的解决方案使用 useState hook: codesandbox

我会注意:

  1. 比较字符串值时,确保它们使用相同的 format/capitalization:
'Feature' === 'FEATURE' //false 
'FEATURE' === 'FEATURE' //true 
  1. 标准化对象中的数据。 JavaScript是动态类型的,所以这样做就可以了:
card.category = 'string'
card.category = ['STRING']

确保数据类型相同,就无需在过滤器函数中进行额外检查。