Home > OS >  Nesting an array of an array in ReactJS
Nesting an array of an array in ReactJS

Time:08-27

I started a new React Project.

I created Images that I imported in:

    import Tip1 from "./img/Tips1.png";
    import Tip2 from "./img/Tips2.png";
    import Tip22 from "./img/Tips2-2.png";
...

I put them into arrays:

const TIP1 = [{ img: Tip1 }];
const TIP2 = [{ img: Tip2 }, { img: Tip22 }, { img: Tip222 }, { img: Tip2222 }];
const TIP3 = [{ img: Tip3 }, { img: Tip31 }, { img: Tip32 }, { img: Tip33 }];
const TIP4 = [{ img: Tip4 }, { img: Tip42 }];

Created extra modal that pops up when we click on the images.

and I created a function that displays these arrays one by one by using .map:

    const Tips = () => {
      const [isOpen, setIsOpen] = useState(false);
      const [selectedImageData, setImageData] = useState({ img: "" });
    
      const onImageClicked = (imageData) => {
        setImageData(imageData);
        setIsOpen(true);
      };

     //Unique ID
      const getUID = () => {
        return Math.ceil((Math.random() * 10000))
      }
    
      return (
        <>
          <div className="mt-5 mb-3">
            <h2> TIP #1 </h2>{" "}
          </div>
    
          {TIP1.map((imageData) => {
            return (
              <div className="card tips--card mt-5 mb-5 me-5 ms-5 ms-auto me-auto" key={getUID()}>
                <img
                  src={imageData.img}
                  alt="Vocab1"
                  className="card-img-top tips--img"
                  onClick={() => onImageClicked(imageData)}
                />
                <div className="card-body"></div>
              </div>
            );
          })}
    
          <div className="row ms-auto me-auto">
            <div className="mt-5 mb-3">
              <h2> TIP #2 </h2>{" "}
            </div>
            {TIP2.map((imageData) => {
              return (
                <div className="card tips--card mt-5 mb-5 me-5 ms-5 ms-auto me-auto" key={getUID()}>
                  <img
                    src={imageData.img}
                    alt="Vocab1"
                    className="card-img-top tips--img"
                    onClick={() => onImageClicked(imageData)}
                  />
                  <div className="card-body"></div>
                </div>
              );
            })}

    ...

And in the end of the function I added the Modal:

...
      {isOpen && (
        //  bind the selected image data state to a data prop on Modal
        <Modal
          // data ={isOpen }
          image={selectedImageData.img}
          //  close the modal
          setIsOpen={setIsOpen}
        />
      )}
    </>
  );
};

The result

It works, but it is not scalable at all, and looks goofy with this much code.

My plan is to create a nested loop by using an extra array:

const TIPS = [
  { TIP: TIP2 },
  { TIP: TIP3 },
  { TIP: TIP4 },
  { TIP: TIP5 },
  { TIP: TIP6 },
  { TIP: TIP7 },
  { TIP: TIP8 },
  { TIP: TIP9 },
];

And this is where I stuck. My best shot was creating an other map so far but it didn't bring closer to the solution.

My question: How could I create a Nested loop that displays the images from the array of an array?

CodePudding user response:

I see what you want, you are already on the right track, all you need to do is to call the map twice.

  {TIP.map((TIPRow, i) => {
    // this is each row
    return (
      <div key={"row"   i}>
        {TIPRow.map(imageData => {
          // this is the image as in your code
        }}
      </div>
    )
  }}

As you said it's nested, you can replace div with any other html structure you want, ex. tr, or li. This is up to you at this point.

NOTE: the challenge is to work with each bracket, [({, so if it's first time, just write slowly, ex. only try to get the first loop working by printing out a row, and then work on second loop. Otherwise the level of bracket could cost you a day ;)

CodePudding user response:

It was a syntactical mistake. Basically, I didn't realize I needed to refer to the previous .map in the second .map and I assumed it will see it automatically.

{TIPS.map((TIPDATA) => {
        return (
          <div >
<div className="row mt-5">
<h2>STEP #{ counter    }</h2>
            {TIPDATA.TIP.map((imageData) => {
              return (
             
                <div className=" card tips--card mt-5 mb-5 me-5 ms-5 ms-auto me-auto" key={getUID()}>
        
             <img
            src={imageData.img}
            alt="Vocab1"
            className="card-img-top tips--img"
            onClick={() => onImageClicked(imageData)}
            key={getUID()}
          />
             </div>
      
              );
              
            }

          
            )
          }
          

</div>
</div>

   
      
        
        );
      })}
  • Related