Mona Omar
Mona Omar

Reputation: 73

Filter images by clicking on buttons that related to using hooks in reactjs

i have images come from file data json and they appear in the page while the project is render but when i click on the buttons above it to filter no images appear

i create if condition when i click on first button it pass pramater call "all" so it should show all images but when i click on other buttons it should show the images that their category includes the pramater that button pass but when i debug it the array comes empty

  "portfolio" : [
      {
          "id":1,
          "image": "./images/Portfolio/portfolio-img1.jpg",
          "category":["html","wordpress","mobile"]
      },
      {
          "id":2,
          "image": "./images/Portfolio/portfolio-img2.jpg",
          "category":["html","photoshop"]
      },
      {
          "id":3,
          "image": "./images/Portfolio/portfolio-img3.jpg",
          "category":["html","wordpress"]

      },
      {
          "id":4,
          "image": "./images/Portfolio/portfolio-img4.jpg",
          "category":["html","mobile"]

      }

  ] ,

  ```
  function Portfolio() {
      const [Images, setImages] = useState([])
  
     useEffect(()=>{
         axios.get('data/data.json').then(res =>{

      setImages(res.data.portfolio)
     })

    },[])
    const handleClick  = (categoryName)=>{
      let test = Images;
      console.log( categoryName);
 
          if(categoryName === 'all'){
              setImages(test)
              console.log(test)
          }else{
              test = Images.filter((img,i)=>{
                  img.category.includes(categoryName)
              })
              setImages(test)
              console.log(test)
          }
     }
       const portfolioImages = Images.map((item, i)=>{
          return(
              <BoxDev key={i}>
                  <Img src={item.image} alt=""/>
                  <Overlay>
                      <BoxSpan>
                          Show Image
                      </BoxSpan>
                  </Overlay>
              </BoxDev>
        )
     })
  
     return (
      <Section>
          <Title><TitleSpan>My</TitleSpan> Portfolio</Title>
          <List>
              <ListItem active onClick={() => handleClick('all')}>All</ListItem>
              <ListItem  onClick={() => handleClick("html" )}>HTML</ListItem>
              <ListItem  onClick={() => handleClick("photoshop")}>Photoshop</ListItem>
              <ListItem  onClick={() => handleClick("wordpress")}>Wordpress</ListItem>
              <ListItem  onClick={() => handleClick("mobile")}>Mobile</ListItem>
          </List>
          
          <div className="box">
              {portfolioImages}
          </div>
      </Section>
   )
}

Upvotes: 0

Views: 645

Answers (2)

palindrom
palindrom

Reputation: 19111

You lose the original Images when you call setImages with filtered images. You need to save categoryName into the state and do the filtering by its value.

const [filter, setFilter] = useState('all');

...


const handleClick  = (categoryName)=>{
    setFilter(categoryName);
}


const portfolioImages = (filter === 'all' ? Images : Images.filter(img => img.category.includes(filter))).map((item, i)=>{
          return(
              <BoxDev key={i}>
                  <Img src={item.image} alt=""/>
                  <Overlay>
                      <BoxSpan>
                          Show Image
                      </BoxSpan>
                  </Overlay>
              </BoxDev>
        )
     })

Upvotes: 1

Rahul
Rahul

Reputation: 5844

You missed to use return condition from filter.

Change this

             test = Images.filter((img,i)=>{
                  img.category.includes(categoryName)
              })

to

 test = Images.filter((img,i)=>{
              return img.category.includes(categoryName)
          })
          

Upvotes: 0

Related Questions