Home > Mobile >  useState set to string not working in Reactjs
useState set to string not working in Reactjs

Time:11-11

I have this code that controls the behavior of what to map from an array onClick. The useState is set to a string const [activeFilter, setActiveFilter] = useState('All'); that is supposed to automatically filter all products containing the string as tag but it doesn't do this automatically and I can't figure out why. Please help with code below.

index.js

import React, { useEffect, useState } from 'react'
import {client} from '../lib/client'
import { Product, FooterBanner, HeroBanner } from '../components'

const Home = ({products, bannerData}) => {
  const [productItems, setProductItems] = useState([])
  const [filterWork, setFilterWork] = useState([]);
  const [activeFilter, setActiveFilter] = useState('All');

  useEffect(() => {
    setProductItems(products)
  }, [])

  const handleProductFilter = (item) => {
    setActiveFilter(item)

    setTimeout(() => {
    if (item == 'All'){
      setFilterWork(productItems)
    }else{
      setFilterWork(productItems.filter((productItem)=> productItem.tags.includes(item)))
    }
  }, 500)
  }

  return (
    <>
      <HeroBanner heroBanner={bannerData.length && bannerData[0]} />
      <div className='products-heading'>
        <h2>Best Selling Products</h2>
        <p>Smoke accessories of many variations</p>
      </div>

      <div className='product_filter'>
          {['Lighter', 'Pipe', 'Roller', 'Hookah', 'All'].map((item, index) => (
            <div
            key={index}
            className={`product_filter-item app__flex p-text ${activeFilter === item ? 'item-active' : ''}`}
            onClick={() => handleProductFilter(item)}
            >
              {item}
            </div>
          ))}
        </div>

      <div className='products-container'>
        {
        filterWork.map((product) => <Product key={product._id} product={product} />)
        }
      </div>

      <FooterBanner footerBanner={bannerData && bannerData[0]} />
    </>
  )
};

export const getServerSideProps = async () => {
  const query = '*[_type == "product"]'
  const products = await client.fetch(query)

  const bannerQuery = '*[_type == "banner"]'
  const bannerData = await client.fetch(bannerQuery)

  return {
    props: {products, bannerData}
  }
}

export default Home

The image below is what it looks like on load and the only time All products containing 'All' tags are visible is when the All button is clicked on again, regardless of it being active initially

enter image description here

CodePudding user response:

No products are being displayed initially when the component renders because the displayed products are loaded from the filterWork state that is only set once an onClick event is triggered. To fix this you can simply set the initial products in the useEffect because you are starting with all the products being displayed.

useEffect(() => {
    setProductItems(products);
    setFilterWork(products);
}, [])
  • Related