1
00:00:02,000 --> 00:00:04,000
Now, rendering our list like this

2
00:00:04,000 --> 00:00:06,000
is of course not our goal.

3
00:00:06,000 --> 00:00:08,000
We want to render a more beautiful,

4
00:00:08,000 --> 00:00:10,000
a more good looking list.

5
00:00:10,000 --> 00:00:14,000
And for this we could structure our code here differently

6
00:00:14,000 --> 00:00:16,000
and add more styling,

7
00:00:16,000 --> 00:00:20,000
but ultimately I simply want to create a new component here

8
00:00:20,000 --> 00:00:23,000
and add component specific styling.

9
00:00:23,000 --> 00:00:24,000
So that's what we'll do.

10
00:00:24,000 --> 00:00:28,000
In the components folder I'll add another subfolder

11
00:00:28,000 --> 00:00:30,000
next to layout, and I'll name it meetups.

12
00:00:30,000 --> 00:00:34,000
And this holds all my meetup specific code.

13
00:00:34,000 --> 00:00:37,000
And in there I'll add a MeetupItem.js file,

14
00:00:37,000 --> 00:00:41,000
and a MeetupList.js file

15
00:00:41,000 --> 00:00:43,000
because I want to outsource both the list

16
00:00:43,000 --> 00:00:46,000
as well as the individual list items

17
00:00:46,000 --> 00:00:48,000
into components.

18
00:00:48,000 --> 00:00:51,000
Because, as mentioned earlier, it is a good practice to

19
00:00:51,000 --> 00:00:54,000
split your components and your application as a whole

20
00:00:54,000 --> 00:00:57,000
into small, reusable pieces.

21
00:00:57,000 --> 00:01:00,000
Now let's start with the MeetupItem.

22
00:01:00,000 --> 00:01:04,000
In that file, we create our MeetupItem function of course,

23
00:01:04,000 --> 00:01:05,000
as we did before,

24
00:01:05,000 --> 00:01:08,000
and we export that function.

25
00:01:08,000 --> 00:01:12,000
Then in here, we return a list item.

26
00:01:12,000 --> 00:01:16,000
And then in that list item, I want to have a div,

27
00:01:16,000 --> 00:01:20,000
in which I render the image and set the source to something

28
00:01:20,000 --> 00:01:22,000
and the alt text to something,

29
00:01:22,000 --> 00:01:25,000
and then that's a self-closing element,

30
00:01:25,000 --> 00:01:30,000
and below that div I have another div with the content,

31
00:01:30,000 --> 00:01:34,000
where I have a h3 tag with the title,

32
00:01:34,000 --> 00:01:38,000
an address tag, which is a default html tag,

33
00:01:38,000 --> 00:01:41,000
where I output the address later,

34
00:01:41,000 --> 00:01:45,000
and then a paragraph with the description.

35
00:01:45,000 --> 00:01:48,000
And all this hard coded text will of course

36
00:01:48,000 --> 00:01:51,000
soon be replaced with dynamic data.

37
00:01:51,000 --> 00:01:54,000
And then below that we can add another div

38
00:01:54,000 --> 00:01:59,000
with a button, where we say to Favorites,

39
00:01:59,000 --> 00:02:04,000
so that this adds the item to our Favorites later.

40
00:02:04,000 --> 00:02:07,000
That's the general structure I want to have here.

41
00:02:07,000 --> 00:02:10,000
Now as mentioned, title, address, and description,

42
00:02:10,000 --> 00:02:14,000
and also the data for the image, should be dynamic.

43
00:02:14,000 --> 00:02:16,000
I don't want to hard code it here.

44
00:02:16,000 --> 00:02:20,000
Instead, it should be passed in from outside,

45
00:02:20,000 --> 00:02:23,000
from the so-called parent component,

46
00:02:23,000 --> 00:02:26,000
so the component where we use this component

47
00:02:26,000 --> 00:02:28,000
in its jsx code.

48
00:02:28,000 --> 00:02:30,000
And we learned how we can make that happen,

49
00:02:30,000 --> 00:02:34,000
we can accept props here and use props.

50
00:02:34,000 --> 00:02:37,000
And then for example, for the image source,

51
00:02:37,000 --> 00:02:41,000
we could set this to props.image,

52
00:02:41,000 --> 00:02:44,000
expecting a image prop on the MeetupItem,

53
00:02:44,000 --> 00:02:49,000
which holds that URL that should be set as a source here.

54
00:02:49,000 --> 00:02:53,000
And the same for the alt text that could be our title.

55
00:02:53,000 --> 00:02:55,000
The title can also be used down there,

56
00:02:55,000 --> 00:02:58,000
so that'd be output props.title here.

57
00:02:58,000 --> 00:03:02,000
And for the address, it's props.address.

58
00:03:02,000 --> 00:03:06,000
For the description, it's props.description.

59
00:03:07,000 --> 00:03:11,000
And now, all of a sudden this component is reusable

60
00:03:11,000 --> 00:03:12,000
and dynamic.

61
00:03:13,000 --> 00:03:15,000
Some styling would also be nice, and for that,

62
00:03:15,000 --> 00:03:19,000
again attach, you find css files here,

63
00:03:19,000 --> 00:03:21,000
the meetupitem.module css

64
00:03:21,000 --> 00:03:25,000
and the meetuplist.module css files,

65
00:03:25,000 --> 00:03:30,000
which you can copy in next to these JavaScript files,

66
00:03:30,000 --> 00:03:33,000
and then in meetupitem.js we want to import

67
00:03:33,000 --> 00:03:38,000
classes from./meetupitem.module.css

68
00:03:40,000 --> 00:03:44,000
and assign a couple of classes in that JavaScript file.

69
00:03:44,000 --> 00:03:46,000
On the list item for example,

70
00:03:46,000 --> 00:03:51,000
we'll add the item class like this on this div,

71
00:03:51,000 --> 00:03:53,000
which is wrapped around the image,

72
00:03:53,000 --> 00:03:57,000
we'll add the image class like this on the div

73
00:03:57,000 --> 00:04:01,000
which is wrapped around the title and description and so on,

74
00:04:01,000 --> 00:04:03,000
we'll add the content class,

75
00:04:03,000 --> 00:04:07,000
and then down there, for the button,

76
00:04:08,000 --> 00:04:12,000
I'll add a class of actions, like this.

77
00:04:13,000 --> 00:04:17,000
Now that's not all. I also want to work on that MeetupList

78
00:04:17,000 --> 00:04:18,000
component already.

79
00:04:18,000 --> 00:04:21,000
So here we can again create another component,

80
00:04:21,000 --> 00:04:26,000
MeetupList, and export that as a default.

81
00:04:26,000 --> 00:04:29,000
Also accept props here, because I expect

82
00:04:29,000 --> 00:04:32,000
to get that list data from outside as well,

83
00:04:32,000 --> 00:04:35,000
and I'm expecting this because I'm the one

84
00:04:35,000 --> 00:04:36,000
building this app.

85
00:04:36,000 --> 00:04:39,000
We could also write the code for fetching meetups

86
00:04:39,000 --> 00:04:43,000
in this component, but I instead want to make this component

87
00:04:43,000 --> 00:04:47,000
reusable and not care about the data source in here,

88
00:04:47,000 --> 00:04:50,000
but instead just expect that I get meetups

89
00:04:50,000 --> 00:04:51,000
through some prop,

90
00:04:51,000 --> 00:04:55,000
and then it's a component which uses the MeetupList

91
00:04:55,000 --> 00:04:58,000
component that has to worry about getting the meetups.

92
00:04:58,000 --> 00:05:00,000
And I'm setting it up like this

93
00:05:00,000 --> 00:05:03,000
because I plan on using the MeetupList component

94
00:05:03,000 --> 00:05:05,000
in the AllMeetups component,

95
00:05:05,000 --> 00:05:08,000
and also in the Favorites component later.

96
00:05:08,000 --> 00:05:11,000
And there we'll have different data sources,

97
00:05:11,000 --> 00:05:14,000
but the same way of displaying the data.

98
00:05:14,000 --> 00:05:16,000
And that's what we can make work

99
00:05:16,000 --> 00:05:19,000
by adding a separate reusable component.

100
00:05:21,000 --> 00:05:25,000
In here I also already wanna import classes

101
00:05:25,000 --> 00:05:30,000
from ./MeetupList.module.css,

102
00:05:30,000 --> 00:05:32,000
and return an unordered list here,

103
00:05:32,000 --> 00:05:36,000
which receives a class name of classes.list

104
00:05:37,000 --> 00:05:42,000
which is the only provided css class for this component.

105
00:05:44,000 --> 00:05:46,000
And inside of the unordered list here,

106
00:05:46,000 --> 00:05:49,000
I now wanna output my MeetupItems

107
00:05:49,000 --> 00:05:53,000
in the same way we did it in AllMeetups,

108
00:05:53,000 --> 00:05:56,000
by mapping an array of objects

109
00:05:56,000 --> 00:05:59,000
into an array of jsx elements.

110
00:05:59,000 --> 00:06:04,000
Just that the jsx elements will now be the list items.

111
00:06:05,000 --> 00:06:08,000
And for this here we again add a dynamic expression

112
00:06:08,000 --> 00:06:09,000
with curly braces,

113
00:06:09,000 --> 00:06:13,000
and we can expect that on our props here

114
00:06:13,000 --> 00:06:17,000
in MeetupList, we get, let's say, a meetups prop,

115
00:06:17,000 --> 00:06:20,000
the name is up to you, because it's your component,

116
00:06:20,000 --> 00:06:22,000
this could all be named items,

117
00:06:22,000 --> 00:06:24,000
but here I'll go with meetups.

118
00:06:24,000 --> 00:06:29,000
And then I'll map every meetup into another object.

119
00:06:30,000 --> 00:06:32,000
Into a jsx element, to be precise.

120
00:06:32,000 --> 00:06:35,000
So therefore, using the arrow function

121
00:06:35,000 --> 00:06:37,000
shorthand subtext here,

122
00:06:37,000 --> 00:06:41,000
I'll transform every meetup into a MeetupItem.

123
00:06:43,000 --> 00:06:46,000
And for this, you need to add this import.

124
00:06:46,000 --> 00:06:49,000
It was automatically added for me here by the IDE.

125
00:06:49,000 --> 00:06:52,000
If that does not work for you, just add it manually,

126
00:06:52,000 --> 00:06:56,000
and import MeetupItem from the MeetupItem file.

127
00:06:57,000 --> 00:07:00,000
Now we render one MeetupItem per object

128
00:07:00,000 --> 00:07:02,000
in the meetups array,

129
00:07:02,000 --> 00:07:04,000
and that now needs to be configured.

130
00:07:04,000 --> 00:07:07,000
It needs this key prop, this special prop,

131
00:07:07,000 --> 00:07:11,000
React expects, one of the very few special props

132
00:07:11,000 --> 00:07:14,000
that are built into React, and that can be used

133
00:07:14,000 --> 00:07:18,000
on any component, including your own components,

134
00:07:18,000 --> 00:07:20,000
without you writing any special code for it

135
00:07:20,000 --> 00:07:22,000
inside of your components.

136
00:07:22,000 --> 00:07:25,000
So you can just add that anywhere.

137
00:07:25,000 --> 00:07:27,000
And we set that equal to Meetup.id.

138
00:07:28,000 --> 00:07:32,000
Then, in my own component, I'll actually pass

139
00:07:32,000 --> 00:07:36,000
in the id as well, as a id prop,

140
00:07:36,000 --> 00:07:39,000
we will use that later for the Favorite feature.

141
00:07:39,000 --> 00:07:44,000
I'll pass in the image prop with meetup.image,

142
00:07:44,000 --> 00:07:48,000
let me reformat this to make it a bit more readable.

143
00:07:48,000 --> 00:07:52,000
At the title prop and point at meetup.title,

144
00:07:53,000 --> 00:07:55,000
and also at address and description.

145
00:07:56,000 --> 00:08:00,000
So meetup.address, and description is equal

146
00:08:00,000 --> 00:08:02,000
to meetup.description.

147
00:08:03,000 --> 00:08:06,000
Now alternatively, we could've also just passed

148
00:08:06,000 --> 00:08:09,000
in a meetup prop, or any other name,

149
00:08:09,000 --> 00:08:12,000
and just passed in the meetup as a whole.

150
00:08:12,000 --> 00:08:14,000
Then we would have to de-structure it

151
00:08:14,000 --> 00:08:17,000
inside of the MeetupItem component.

152
00:08:17,000 --> 00:08:19,000
It's up to you which approach you prefer,

153
00:08:19,000 --> 00:08:22,000
here I'm passing in individual props.

154
00:08:23,000 --> 00:08:25,000
With all of that done, though,

155
00:08:25,000 --> 00:08:26,000
we can go back to AllMeetups

156
00:08:26,000 --> 00:08:29,000
and now use the meetup list component

157
00:08:29,000 --> 00:08:32,000
instead of the unordered list.

158
00:08:32,000 --> 00:08:36,000
So we go up and we import.

159
00:08:36,000 --> 00:08:40,000
MeetupList from, going up one level,

160
00:08:40,000 --> 00:08:42,000
out of the pages folder,

161
00:08:42,000 --> 00:08:44,000
into the components folder,

162
00:08:44,000 --> 00:08:46,000
into the meetups folder,

163
00:08:46,000 --> 00:08:46,000
to MeetupList,

164
00:08:48,000 --> 00:08:52,000
and then just output MeetupList like this,

165
00:08:54,000 --> 00:08:58,000
and very important, provide the meetups' prop.

166
00:08:58,000 --> 00:09:01,000
Because we're expecting that prop inside

167
00:09:01,000 --> 00:09:03,000
of the MeetupList component, here.

168
00:09:05,000 --> 00:09:07,000
So set up the meetups prop here,

169
00:09:07,000 --> 00:09:09,000
and pass in the dummy data array

170
00:09:09,000 --> 00:09:11,000
as a value.

171
00:09:11,000 --> 00:09:14,000
With all of that done, if you save all the files,

172
00:09:14,000 --> 00:09:16,000
you should see something like this.

173
00:09:17,000 --> 00:09:19,000
Now this is not the final look,

174
00:09:19,000 --> 00:09:21,000
we'll continue tweaking this,

175
00:09:21,000 --> 00:09:25,000
but it shows that our content is being rendered.

176
00:09:25,000 --> 00:09:27,000
And that's not too bad.

177
00:09:27,000 --> 00:09:31,000
But now it would be nice to kind of restrict the width,

178
00:09:31,000 --> 00:09:33,000
which we use on the screen,

179
00:09:33,000 --> 00:09:36,000
and it would also be nice if the individual meetups

180
00:09:36,000 --> 00:09:40,000
would look like cards, with a nice drop shadow,

181
00:09:40,000 --> 00:09:44,000
maybe rounded corners, something like that.

182
00:09:44,000 --> 00:09:46,000
That's what we're going to add next.

