Home > Blockchain >  how to toggle a boolean inside an array
how to toggle a boolean inside an array

Time:11-07

import React, { useState } from "react";
import { v4 as uuidv4 } from 'uuid';

const ReturantInfo = ()=>{
     const data = [
          {
               name: "Haaland Restaurant's",
               stars: 5,
               price:"100$",
               ranking:"top 1 in england",
               ids:[
                    {id:uuidv4(),key:uuidv4(),visibility:false},
                    {id:uuidv4(),key:uuidv4(),visibility:false},
                    {id:uuidv4(),key:uuidv4(),visibility:false},
               ]
          }
     ]
     const [restaurantData,setRestaurantData] = useState(data)
     const CardElement = restaurantData.map((data)=>{
          return(
               <div style={{color:"white"}}>
                    <h1>{data.name}</h1>
                    <div>
                         <div>
                              <h1>Stars</h1>
                              <p
                                   id={data.ids[0].id}
                                   onClick={()=>toggleVisibility(data.ids[0].id)}
                              >show</p>
                         </div>
                         { data.ids[0].visibility ? <p>{data.stars}</p> : ""}
                    </div>
                    <div>
                         <div>
                              <h1>Price</h1>
                              <p
                                   id={data.ids[1].id}
                                   onClick={()=>toggleVisibility(data.ids[1].id)}
                              >show</p>
                         </div>
                         { data.ids[1].visibility ? <p>{data.price}</p> : ""}
                    </div>
                    <div>
                         <div>
                              <h1>Ranking</h1>
                              <p
                                   id={data.ids[2].id}
                                   onClick={()=>toggleVisibility(data.ids[2].id)}
                              >show</p>
                         </div>
                         { data.ids[2].visibility ? <p>{data.ranking}</p> : ""}
                    </div>
               </div>
          )
     })
     function toggleVisibility(id) {
          setRestaurantData((prevData) =>
            prevData.map((data) => {
               data.ids.map(h=>{
                    return h.id === id ? {...data,ids:[{...h,visibility:!h.visibility}]} : data
               })
            })
          );
        }
     return(
          <div>
               {CardElement}
          </div>
     )
} 
export default ReturantInfo

that's a small example from my project I want to toggle visibility property by depending on the id of the clicked element and then if it equals to the id in the array then change the visibility to the opposite.

CodePudding user response:

It looks like your handler isn't mapping the data to the same shape as what was there previously. Your data structure is quite complex which doesn't make the job easy, but you could use an approach more like this, where you pass in the element of data that needs to be modified, as well as the index of hte ids array that you need to modify, then return a callback that you can use as the onClick handler:

function toggleVisibility(item, index) {
  return () => {
    setRestaurantData((prevData) => prevData.map((prevItem) => {
      if (prevItem !== item) return prevItem;

      return {
        ...prevItem,
        ids: prevItem.ids.map((id, i) =>
          i !== index ? id : { ...id, visibility: !id.visibility }
        ),
      };
    }));
  };
}

And you'd use it like this:

<p onClick={toggleVisibility(data, 0)}>show</p>

While you're there, you could refactor out each restaurant "property" into a reusable component, since they're all effectively doing the same thing. Here's a StackBlitz showing it all working.

CodePudding user response:

  function toggleVisibility(id) {
    setRestaurantData(prevData => {
      return prevData.map(data => {
        data.ids.map(h => {
          return h.id === id ? (h.visibility = !h.visibility) : h.visibility;
        });
        return data;
      });
    });
  }
  • Related