Now, rendering our list like this
is of course not our goal.
We want to render a more beautiful,
a more good looking list.
And for this we could structure our code here differently
and add more styling,
but ultimately I simply want to create a new component here
and add component specific styling.
So that's what we'll do.
In the components folder I'll add another subfolder
next to layout, and I'll name it meetups.
And this holds all my meetup specific code.
And in there I'll add a MeetupItem.js file,
and a MeetupList.js file
because I want to outsource both the list
as well as the individual list items
into components.
Because, as mentioned earlier, it is a good practice to
split your components and your application as a whole
into small, reusable pieces.
Now let's start with the MeetupItem.
In that file, we create our MeetupItem function of course,
as we did before,
and we export that function.
Then in here, we return a list item.
And then in that list item, I want to have a div,
in which I render the image and set the source to something
and the alt text to something,
and then that's a self-closing element,
and below that div I have another div with the content,
where I have a h3 tag with the title,
an address tag, which is a default html tag,
where I output the address later,
and then a paragraph with the description.
And all this hard coded text will of course
soon be replaced with dynamic data.
And then below that we can add another div
with a button, where we say to Favorites,
so that this adds the item to our Favorites later.
That's the general structure I want to have here.
Now as mentioned, title, address, and description,
and also the data for the image, should be dynamic.
I don't want to hard code it here.
Instead, it should be passed in from outside,
from the so-called parent component,
so the component where we use this component
in its jsx code.
And we learned how we can make that happen,
we can accept props here and use props.
And then for example, for the image source,
we could set this to props.image,
expecting a image prop on the MeetupItem,
which holds that URL that should be set as a source here.
And the same for the alt text that could be our title.
The title can also be used down there,
so that'd be output props.title here.
And for the address, it's props.address.
For the description, it's props.description.
And now, all of a sudden this component is reusable
and dynamic.
Some styling would also be nice, and for that,
again attach, you find css files here,
the meetupitem.module css
and the meetuplist.module css files,
which you can copy in next to these JavaScript files,
and then in meetupitem.js we want to import
classes from./meetupitem.module.css
and assign a couple of classes in that JavaScript file.
On the list item for example,
we'll add the item class like this on this div,
which is wrapped around the image,
we'll add the image class like this on the div
which is wrapped around the title and description and so on,
we'll add the content class,
and then down there, for the button,
I'll add a class of actions, like this.
Now that's not all. I also want to work on that MeetupList
component already.
So here we can again create another component,
MeetupList, and export that as a default.
Also accept props here, because I expect
to get that list data from outside as well,
and I'm expecting this because I'm the one
building this app.
We could also write the code for fetching meetups
in this component, but I instead want to make this component
reusable and not care about the data source in here,
but instead just expect that I get meetups
through some prop,
and then it's a component which uses the MeetupList
component that has to worry about getting the meetups.
And I'm setting it up like this
because I plan on using the MeetupList component
in the AllMeetups component,
and also in the Favorites component later.
And there we'll have different data sources,
but the same way of displaying the data.
And that's what we can make work
by adding a separate reusable component.
In here I also already wanna import classes
from ./MeetupList.module.css,
and return an unordered list here,
which receives a class name of classes.list
which is the only provided css class for this component.
And inside of the unordered list here,
I now wanna output my MeetupItems
in the same way we did it in AllMeetups,
by mapping an array of objects
into an array of jsx elements.
Just that the jsx elements will now be the list items.
And for this here we again add a dynamic expression
with curly braces,
and we can expect that on our props here
in MeetupList, we get, let's say, a meetups prop,
the name is up to you, because it's your component,
this could all be named items,
but here I'll go with meetups.
And then I'll map every meetup into another object.
Into a jsx element, to be precise.
So therefore, using the arrow function
shorthand subtext here,
I'll transform every meetup into a MeetupItem.
And for this, you need to add this import.
It was automatically added for me here by the IDE.
If that does not work for you, just add it manually,
and import MeetupItem from the MeetupItem file.
Now we render one MeetupItem per object
in the meetups array,
and that now needs to be configured.
It needs this key prop, this special prop,
React expects, one of the very few special props
that are built into React, and that can be used
on any component, including your own components,
without you writing any special code for it
inside of your components.
So you can just add that anywhere.
And we set that equal to Meetup.id.
Then, in my own component, I'll actually pass
in the id as well, as a id prop,
we will use that later for the Favorite feature.
I'll pass in the image prop with meetup.image,
let me reformat this to make it a bit more readable.
At the title prop and point at meetup.title,
and also at address and description.
So meetup.address, and description is equal
to meetup.description.
Now alternatively, we could've also just passed
in a meetup prop, or any other name,
and just passed in the meetup as a whole.
Then we would have to de-structure it
inside of the MeetupItem component.
It's up to you which approach you prefer,
here I'm passing in individual props.
With all of that done, though,
we can go back to AllMeetups
and now use the meetup list component
instead of the unordered list.
So we go up and we import.
MeetupList from, going up one level,
out of the pages folder,
into the components folder,
into the meetups folder,
to MeetupList,
and then just output MeetupList like this,
and very important, provide the meetups' prop.
Because we're expecting that prop inside
of the MeetupList component, here.
So set up the meetups prop here,
and pass in the dummy data array
as a value.
With all of that done, if you save all the files,
you should see something like this.
Now this is not the final look,
we'll continue tweaking this,
but it shows that our content is being rendered.
And that's not too bad.
But now it would be nice to kind of restrict the width,
which we use on the screen,
and it would also be nice if the individual meetups
would look like cards, with a nice drop shadow,
maybe rounded corners, something like that.
That's what we're going to add next.