So I have a js file where I store all of my data, and I will map out that js file to render the data I want to render. To stop myself from rendering all the data, I have made it so that it only conditionally renders every time title = element.id, therefore it should only render out the data that has the id specific id of the title. However, although this works, it ends up rendering a bunch of empty divs, and so this pushes my actual data down. Image of my data being pushed down As you can see the empty divs have pushed my actual data down a lot inside of my modal.
Does anybody know how to stop this from happening? (How to get rid of the space above by stopping the rendering of the blanks divs maybe?)
My modal file looks like this
const Modal = ({ handleClose, id, title, subtitle, description, techStack, image, github, devpost }) => {
let isId = false;
return (
<Backdrop onClick={handleClose}>
<motion.div
onClick={(e) => e.stopPropagation()}
className='modal-ics'
variants={dropIn}
initial='hidden'
animate='visible'
exit='exit'
>
<div className='w-full flex flex-col items-center'>
<ModalButton onClick={handleClose} label='Close'></ModalButton>
<div className='flex flex-col w-full h-full justify-between items-start'>
hello
{ICSData.map((element) => {
if (id == element.id) {
isId = true;
}
else {
isId = false;
}
return (
<div>
{ isId &&
<div>
<div className='modal-text-separator'>
<h1 className='modal-title'>{element.title}</h1>
<h3 className='modal-date'>{element.subtitle1}</h3>
<p className='modal-description mt-2'>{element.description1}</p>
</div>
{ element.subtitle2 &&
<div className='modal-text-separator'>
<h3 className='modal-date'>{element.subtitle2}</h3>
<p className='modal-description mt-2'>{element.description2}</p>
</div>
}
{ element.subtitle3 &&
<div className='modal-text-separator'>
<h3 className='modal-date'>{element.subtitle3}</h3>
<p className='modal-description mt-2'>{element.description3}</p>
</div>
}
{ element.subtitle4 &&
<div className='modal-text-separator'>
<h3 className='modal-date'>{element.subtitle4}</h3>
<p className='modal-description mt-2'>{element.description4}</p>
</div>
}
{ element.subtitle5 &&
<div className='modal-text-separator'>
<h3 className='modal-date'>{element.subtitle5}</h3>
<p className='modal-description mt-2'>{element.description5}</p>
</div>
}
</div>
}
</div>
);
})}
</div>
</div>
</motion.div>
</Backdrop>
)
}
export default Modal;
My data file looks like this
import React from 'react'
const ICSData = [
{
id: "classes",
title: "Classes",
image: "InspiritAI.png" ,
subtitle1: "very cool subtitle",
description1:
"this is a very cool description",
subtitle2: "very cool subtitle",
description2:
"this is a very cool description",
subtitle3: "very cool subtitle",
description3:
"this is a very cool description",
subtitle4: "very cool subtitle",
description4:
"this is a very cool description",
subtitle5: "very cool subtitle",
description5:
"this is a very cool description",
},
{
id: "documentation-ds",
title: "Documentation",
image: "InspiritAI.png" ,
subtitle1: "very cool subtitle",
description1:
"this is a very cool description",
subtitle2: "very cool subtitle",
description2:
"this is a very cool description",
subtitle3: "very cool subtitle",
description3:
"this is a very cool description",
subtitle4: "very cool subtitle",
description4:
"this is a very cool description",
subtitle5: "very cool subtitle",
description5:
"this is a very cool description",
},
{
id: "file-reading-and-writing",
title: "File Reading and Writing",
image: "InspiritAI.png" ,
subtitle1: "very cool subtitle",
description1:
"this is a very cool description",
subtitle2: "very cool subtitle",
description2:
"this is a very cool description",
subtitle3: "very cool subtitle",
description3:
"this is a very cool description",
subtitle4: "very cool subtitle",
description4:
"this is a very cool description",
subtitle5: "very cool subtitle",
description5:
"this is a very cool description",
},
{
id: "object-concepts",
title: "Object Concepts",
image: "InspiritAI.png" ,
subtitle1: "very cool subtitle",
description1:
"this is a very cool description",
subtitle2: "very cool subtitle",
description2:
"this is a very cool description",
subtitle3: "very cool subtitle",
description3:
"this is a very cool description",
subtitle4: "very cool subtitle",
description4:
"this is a very cool description",
subtitle5: "very cool subtitle",
description5:
"this is a very cool description",
},
{
id: "uml-diagrams",
title: "UML Diagrams",
image: "InspiritAI.png" ,
subtitle1: "very cool subtitle",
description1:
"this is a very cool description",
subtitle2: "very cool subtitle",
description2:
"this is a very cool description",
subtitle3: "very cool subtitle",
description3:
"this is a very cool description",
subtitle4: "very cool subtitle",
description4:
"this is a very cool description",
subtitle5: "very cool subtitle",
description5:
"this is a very cool description",
},
{
id: "documentation-algorithms",
title: "Documentation",
image: "InspiritAI.png" ,
subtitle1: "very cool subtitle",
description1:
"this is a very cool description",
subtitle2: "very cool subtitle",
description2:
"this is a very cool description",
subtitle3: "very cool subtitle",
description3:
"this is a very cool description",
subtitle4: "very cool subtitle",
description4:
"this is a very cool description",
subtitle5: "very cool subtitle",
description5:
"this is a very cool description",
}
]
export default ICSData;
CodePudding user response:
The reason why you end up having multiple empty divs where there shouldn't be lies in your return statement of the mapping:
{ICSData.map((element) => {
if (id == element.id) {
isId = true;
}
else {
isId = false;
}
return (
<div>
{ isId &&
<div>
<div className='modal-text-separator'>
...
}
</div>
)
...
Here, you're still creating a div whether there should be or not. The easiest fix would be to return an empty element if your id doesn't match, like this:
{ICSData.map(element => {
if (id == element.id) {
return (
<YOUR_CODE />
)
} else {
return <></>
}
}
However, looping through all your data to show one element probably isn't the best idea. A few alternatives:
- change your data so that instead of being an array, it's an object of objects, with the key being an entry's ID and the values being the rest of your data (assuming all your IDs are unique)
- use the find function (once again assuming your IDs are unique)
I'll just go over the second solution since it doesn't involve changing your data and is just more straightforward. However, it is slower than the first solution as the .find
function would be O(n), compared to the first solution would be O(1). This likely doesn't matter if you have little data, but is something to keep in mind if the number of items in your ICSData
array grows.
You can implement the second solution using one line:
const data = ICSData.find(element => id === element.id)
// Do whatever you want with this var in your component
CodePudding user response:
You could just limit it by only calling the map function up until a certain ID
{ICSData.filter((item, idx) => idx < 5).map((element) => {...})}
And then you can also replace the 5 with a variable that controls that number if you want to make a load more button.