Home > OS >  React how to call function depends on specific element id
React how to call function depends on specific element id

Time:09-27

how I can tigress an function depends on id of an element. Right now all elements getting clicked if I click on any single element. how to prevent to show all element ? here is my code

const[showsubcat,setShowSubCat] = useState(false)
   
   let subcategory=(()=>{
             
             setShowSubCat(prev=>!prev)
       }) 

my jsx

{data.map((data)=>{
                         return(
                          <>
                           
                          <li  id={data.id}    onClick={subcategory} >{data.main_category}</li>
                            {showsubcat && 
                          <li><i  id="sub_category"></i> {data.sub_category}</li>
                          }
                          
                          </>
                             

                         )

see the screenshot. I am clicking on single items but it's showing all items.

enter image description here

CodePudding user response:

Every li should have it own state so it's either you create states based on number of li if they're just 2 elements max! but it's ugly and when you want to add more li it's gonna be a mess
so you just create a component defining the ListItem and every component has it own state.

 function ListItem({data}) {
 const[showsubcat,setShowSubCat] = useState(false)

  const subcategory= ()=> setShowSubCat(prev=>!prev) 

 return (
         <>              
   <li  id={data.id}    onClick={subcategory} > 
       {data.main_category}
   </li>
   {showsubcat && 
     <li>
        <i  id="sub_category"></i> 
        {data.sub_category}
     </li>                     
    }
  </>
                      
)
}

and you use it in the list component like this

data.map((datum, index) => <ListItem key={index} data={datum} />

EDIT AFTER THE POST UPDATE (misunderstanding)

the list item (or the block containing the li and the helper text) should be an independant component to manage it own state

function PostAds(data) => {
  return ( 
   <>
   {
   data.map((data, index) => <ListItem key={index} data {data}/> 
   }
   </>
  )
}

function ListItem({data}) {
  const [showsubcat, setShowSubCat] = useState(false)

  const subcategory = () => setShowSubCat(prev => !prev)

  return (
       <>
      <li 
         
         id={data.id}
         onClick={subcategory}> 
         {data.main_category} 
      </li> 
      {
      showsubcat &&
      <li >
        <i  class = "las la-angle-right" id = "sub_category"></i>  
        {data.sub_category} 
      </li>                     
      }
    </>
)

}

CodePudding user response:

The reason this is happening is because you are using the same variable showsubcat to check if the category was clicked or not.

A proper way to do this would be by either making showsubcat as an array that holds ids of those categories that were clicked like:

const[showsubcat,setShowSubCat] = useState([])
   
let subcategory=((categoryId)=> 
 showsubcat.includes(categoryId) ?  
   setShowSubCat(showsubcat.filter(el => el !== categoryId)) :  
   setShowSubCat([...showsubcat, categoryId]));

and then while mapping the data:

{data.map((category)=>
   (
      <>
         <li  id={category.id} key={category.id}    
          onClick={() => subcategory(category.id)}>
            {category.main_category}
         </li>
        
         {showsubcat.includes(category.id) && 
                          <li>
                              <i  
                               id="sub_category" key={`subCategory${category.id}`} /> 
                              {category.sub_category} 
                          </li>
         }                        
      </>
  )
}

The other method would be to add a new key in your data array as selectedCategory and change its value to true/false based on the click, but this is a bit lengthy, let me know if you still want to know that process.

Also, accept the answer if it helps!

  • Related