Creating a Shared Post List Component
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

WEBVTT

1
00:00:00.530 --> 00:00:03.010
Now that we're getting our post back when we're running

2
00:00:03.010 --> 00:00:07.240
queries, now it's time to start showing them on the screen.

3
00:00:07.240 --> 00:00:10.926
Now the way that we're gonna show them is gonna be identical

4
00:00:10.926 --> 00:00:15.926
to how we show them on the normal feed page.

5
00:00:15.940 --> 00:00:18.820
Whenever you run into a scenario like that,

6
00:00:18.820 --> 00:00:22.410
where you are working on pretty much duplicate

7
00:00:22.410 --> 00:00:25.840
implementations, on different parts of the application,

8
00:00:25.840 --> 00:00:30.440
it's a good indicator that that component, or that behavior,

9
00:00:30.440 --> 00:00:33.480
could be broken out into a shared component.

10
00:00:33.480 --> 00:00:36.680
And that's exactly what we're gonna do in this guide.

11
00:00:36.680 --> 00:00:40.930
We're gonna create what is called a PostList component,

12
00:00:40.930 --> 00:00:43.670
and that's gonna be something that we can call

13
00:00:43.670 --> 00:00:48.090
from the FeedScreen and we can call from the SearchScreen.

14
00:00:48.090 --> 00:00:50.440
So let's get started with that.

15
00:00:50.440 --> 00:00:53.580
I'm going to open up the file system,

16
00:00:53.580 --> 00:00:57.420
and then inside of components and then posts,

17
00:00:57.420 --> 00:00:59.680
I'm going to create a new file,

18
00:00:59.680 --> 00:01:04.190
here, called Postlist dot tsx.

19
00:01:04.190 --> 00:01:07.490
And then inside of here, this is where we're gonna build out

20
00:01:07.490 --> 00:01:10.850
and we're gonna start integrating all of our imports,

21
00:01:10.850 --> 00:01:14.910
we're gonna create an interface and then we're gonna add

22
00:01:14.910 --> 00:01:16.980
the component code itself.

23
00:01:16.980 --> 00:01:19.480
So let's talk about what we're gonna need.

24
00:01:19.480 --> 00:01:21.460
We're not gonna need any state.

25
00:01:21.460 --> 00:01:23.070
For lack of a better term

26
00:01:23.070 --> 00:01:26.010
this is gonna be a very dumb component.

27
00:01:26.010 --> 00:01:29.490
We do not want this to have very much business logic,

28
00:01:29.490 --> 00:01:32.715
if any logic at all, we simply want to have a way

29
00:01:32.715 --> 00:01:36.320
that we can pass data to it and then have that data

30
00:01:36.320 --> 00:01:38.200
rendered on the screen.

31
00:01:38.200 --> 00:01:41.300
So we're not gonna use any state here, we're simply

32
00:01:41.300 --> 00:01:45.430
going to import React from react

33
00:01:45.430 --> 00:01:49.200
and then let's talk about what we're going to need.

34
00:01:49.200 --> 00:01:52.739
Well, we wanna have a ScrollView because,

35
00:01:52.739 --> 00:01:55.390
as we've already seen on our FeedScreen,

36
00:01:55.390 --> 00:01:58.230
users need the ability to scroll up and down

37
00:01:58.230 --> 00:01:59.760
to see all of the posts.

38
00:01:59.760 --> 00:02:02.310
And, then, we also need the ability

39
00:02:02.310 --> 00:02:05.410
for this to be something that can be clicked.

40
00:02:05.410 --> 00:02:07.230
So right away that should tell you

41
00:02:07.230 --> 00:02:09.960
that we need two components from React Native.

42
00:02:09.960 --> 00:02:13.320
We need TouchableOpacity and we need a ScrollView.

43
00:02:13.320 --> 00:02:17.010
So I'm gonna say import, curly brackets, ScrollView

44
00:02:18.070 --> 00:02:21.820
and then TouchableOpacity...

45
00:02:24.036 --> 00:02:29.036
And then that's gonna be from react dash native.

46
00:02:30.850 --> 00:02:34.430
Okay, then we know we're gonna need a PostItem

47
00:02:35.400 --> 00:02:38.250
because, and I'm not making this stuff up,

48
00:02:38.250 --> 00:02:40.460
or even just going off the top of my head,

49
00:02:40.460 --> 00:02:43.430
I'm just thinking about how we created our FeedScreen.

50
00:02:43.430 --> 00:02:45.890
Because, essentially, what we're gonna be doing

51
00:02:45.890 --> 00:02:50.550
is everything right here is going to be moved out

52
00:02:50.550 --> 00:02:53.500
into our PostList component.

53
00:02:53.500 --> 00:02:56.370
And at some point we may even just copy this.

54
00:02:56.370 --> 00:02:58.860
So, right there, we can use this as a reference.

55
00:02:58.860 --> 00:03:00.510
We know we're gonna need a ScrollView.

56
00:03:00.510 --> 00:03:02.630
We can see the styles we're gonna need.

57
00:03:02.630 --> 00:03:04.600
We know we need TouchableOpacity.

58
00:03:04.600 --> 00:03:06.950
We know that we're gonna need a PostItem.

59
00:03:06.950 --> 00:03:10.220
So let's go get that PostItem now too.

60
00:03:10.220 --> 00:03:15.000
So I'm gonna say import PostItem from dot dot slash,

61
00:03:15.000 --> 00:03:16.810
and you know what, actually, this is just gonna be

62
00:03:16.810 --> 00:03:20.020
dot slash, and there ya go, we have our PostItem,

63
00:03:20.020 --> 00:03:22.060
we're in the same directory as that.

64
00:03:22.060 --> 00:03:24.100
Remember anytime you're doing an import,

65
00:03:24.100 --> 00:03:27.900
from the same directory, the syntax is dot slash

66
00:03:27.900 --> 00:03:30.620
and then the name of whatever you're importing.

67
00:03:30.620 --> 00:03:34.730
And then lastly, we already saw how our FeedScreen

68
00:03:34.730 --> 00:03:37.850
had these baseStyles, with the container

69
00:03:37.850 --> 00:03:39.510
with bottom tab bar.

70
00:03:39.510 --> 00:03:42.160
Well let's go get those baseStyles as well.

71
00:03:42.160 --> 00:03:47.160
So I'm gonna say import baseStyles from dot dot slash

72
00:03:47.549 --> 00:03:52.410
dot dot slash styles, and I believe that is in common

73
00:03:52.410 --> 00:03:54.230
and yes, baseStyles.

74
00:03:54.230 --> 00:03:55.170
There we go.

75
00:03:55.170 --> 00:03:58.100
Okay, so that's the first part of it.

76
00:03:58.100 --> 00:04:00.190
Now let's create the interface because, remember,

77
00:04:00.190 --> 00:04:03.110
you know that I like to, before I really start

78
00:04:03.110 --> 00:04:05.890
getting in and writing my component code,

79
00:04:05.890 --> 00:04:09.450
I like to think about the type of component data

80
00:04:09.450 --> 00:04:10.980
that this is gonna work with.

81
00:04:10.980 --> 00:04:13.950
So let's talk about building out our interface.

82
00:04:13.950 --> 00:04:16.850
So this interface is gonna be interface called

83
00:04:16.850 --> 00:04:21.850
iPostListProps, and inside of here

84
00:04:22.710 --> 00:04:24.690
we're gonna get two elements.

85
00:04:24.690 --> 00:04:27.540
We know we're gonna get a list of Posts,

86
00:04:27.540 --> 00:04:29.390
and for right now I'm just gonna call that any.

87
00:04:29.390 --> 00:04:32.340
It's gonna be an array but we're just gonna call it any.

88
00:04:32.340 --> 00:04:36.260
And then we know we're gonna need the ability to navigate.

89
00:04:36.260 --> 00:04:39.500
Cuz, remember, our items, each one of these items,

90
00:04:39.500 --> 00:04:42.880
if you reference the FeedScreen, they have TouchableOpacity

91
00:04:42.880 --> 00:04:46.590
and then this handleItemPress function,

92
00:04:46.590 --> 00:04:50.300
which is wired up to the navigation system.

93
00:04:50.300 --> 00:04:54.020
So we know we're gonna have to be able to navigate

94
00:04:54.020 --> 00:04:56.648
and, also, we could just do any, but instead,

95
00:04:56.648 --> 00:04:58.530
because we're good developers,

96
00:04:58.530 --> 00:05:00.840
we're gonna be more explicit here.

97
00:05:00.840 --> 00:05:04.410
We're gonna go with the screenName, which is a string

98
00:05:04.410 --> 00:05:07.760
and the second one which is gonna be the data,

99
00:05:07.760 --> 00:05:10.490
which that is one we'll just say any for.

100
00:05:10.490 --> 00:05:15.490
And then that's gonna be a fat arrow function to void.

101
00:05:15.690 --> 00:05:18.440
So those are the two items that we're gonna need.

102
00:05:18.440 --> 00:05:20.850
We're gonna need a list of posts,

103
00:05:20.850 --> 00:05:22.840
and then from there we're gonna need

104
00:05:22.840 --> 00:05:24.710
the ability to navigate.

105
00:05:24.710 --> 00:05:27.480
So I think that's all we're gonna have to have there.

106
00:05:27.480 --> 00:05:30.140
Now lets actually build out the function itself.

107
00:05:30.140 --> 00:05:34.160
So export default, and we know we're gonna take in props

108
00:05:34.160 --> 00:05:38.030
and this is going to be of type IPostListProps

109
00:05:39.300 --> 00:05:41.880
and that's gonna be a fat arrow function.

110
00:05:41.880 --> 00:05:46.630
And inside of here, we're going to return some data.

111
00:05:46.630 --> 00:05:49.620
Now first, and foremost, we know we're going to return,

112
00:05:49.620 --> 00:05:52.050
once again referencing our FeedScreen,

113
00:05:52.050 --> 00:05:54.957
we know we're going to have a ScrollView.

114
00:05:54.957 --> 00:05:57.250
Let's actually take all of this out.

115
00:05:57.250 --> 00:05:58.930
Now it's time to cut this.

116
00:05:58.930 --> 00:06:02.670
So I'm gonna cut this here and now, let's just say,

117
00:06:02.670 --> 00:06:05.300
return our ScrollView.

118
00:06:05.300 --> 00:06:07.270
Now we have some errors here because, obviously,

119
00:06:07.270 --> 00:06:10.150
we haven't accessed the data yet, that's perfectly fine.

120
00:06:10.150 --> 00:06:13.800
So this is our ScrollView, we have access to our baseStyles.

121
00:06:13.800 --> 00:06:18.040
And then we're gonna start iterating over each of those.

122
00:06:18.040 --> 00:06:21.620
So we know we're gonna get access to the post through props,

123
00:06:21.620 --> 00:06:26.080
so here I'm gonna say props dot posts.map,

124
00:06:26.080 --> 00:06:29.300
and we also need this handleItemPress function.

125
00:06:29.300 --> 00:06:31.350
So let's go get that form the FeedScreen.

126
00:06:32.381 --> 00:06:35.920
HandleItemPress, just gonna cut it because this component

127
00:06:35.920 --> 00:06:37.870
is no longer gonna need it.

128
00:06:37.870 --> 00:06:41.660
And, so, inside of the function I'll paste that in,

129
00:06:41.660 --> 00:06:44.790
and you can see it says props.navigation.navigate,

130
00:06:44.790 --> 00:06:46.880
it's because I just kinda streamlined

131
00:06:46.880 --> 00:06:49.620
how this function call was going to occur.

132
00:06:49.620 --> 00:06:51.330
So let's not even worry about that.

133
00:06:51.330 --> 00:06:55.660
It's just gonna be props dot navigate,

134
00:06:55.660 --> 00:06:57.980
and now that errors gone.

135
00:06:57.980 --> 00:07:00.640
Okay, so, so far this looks pretty good.

136
00:07:00.640 --> 00:07:03.720
It's nowhere near done but it's definitely getting closer.

137
00:07:03.720 --> 00:07:05.400
Let's see how far we are away.

138
00:07:05.400 --> 00:07:09.320
I'm gonna just hit save here and then let's try to call

139
00:07:09.320 --> 00:07:10.830
this and see what happens.

140
00:07:10.830 --> 00:07:12.800
So I'm gonna go back to the FeedScreen

141
00:07:12.800 --> 00:07:16.020
and now I can even get rid of these parens here,

142
00:07:16.020 --> 00:07:21.020
which is kinda cool and I can import our PostList component.

143
00:07:21.170 --> 00:07:26.170
PostList and then what does this need?

144
00:07:26.300 --> 00:07:28.770
Once again it needs our list of posts.

145
00:07:28.770 --> 00:07:31.130
So we're gonna pass those in as a prop

146
00:07:31.130 --> 00:07:33.890
and then it needs the navigate function.

147
00:07:33.890 --> 00:07:38.317
So we're gonna call that with props dot navigation

148
00:07:38.317 --> 00:07:40.383
dot navigate.

149
00:07:41.340 --> 00:07:44.660
Okay let's hit save and look at that.

150
00:07:44.660 --> 00:07:48.580
We have, even though we're on the same screen,

151
00:07:48.580 --> 00:07:51.220
we've gotten rid of all of that code

152
00:07:51.220 --> 00:07:53.950
and moved it into a PostList component

153
00:07:53.950 --> 00:07:56.270
and it's still working perfectly.

154
00:07:56.270 --> 00:07:58.180
So this is still working really nice.

155
00:07:58.180 --> 00:07:59.810
If I click on one of these,

156
00:07:59.810 --> 00:08:02.330
it's still taking me to the detail screen.

157
00:08:02.330 --> 00:08:05.160
Everything there is working perfectly.

158
00:08:05.160 --> 00:08:08.720
So we've completely refactored our FeedScreen,

159
00:08:08.720 --> 00:08:10.460
so that is great.

160
00:08:10.460 --> 00:08:12.690
Now let's see if we can do a little bit better.

161
00:08:12.690 --> 00:08:15.720
Let's see if we can refactor our PostList

162
00:08:15.720 --> 00:08:20.690
because this code is okay, but we really can do better

163
00:08:20.690 --> 00:08:23.337
especially because I'm wanting to teach you

164
00:08:23.337 --> 00:08:26.840
how to work in more advanced type of environment,

165
00:08:26.840 --> 00:08:29.330
and, so, this code would work

166
00:08:29.330 --> 00:08:31.060
but there would be some bugs with it.

167
00:08:31.060 --> 00:08:33.200
So let's start cleaning those up.

168
00:08:33.200 --> 00:08:35.230
The very first thing that I'm gonna do

169
00:08:35.230 --> 00:08:39.010
is I'm gonna create a Render function here.

170
00:08:39.010 --> 00:08:42.837
So I'm going to say const postsRenderer

171
00:08:44.980 --> 00:08:46.910
and it's just gonna be a fat arrow function,

172
00:08:46.910 --> 00:08:49.050
that doesn't take in any arguments,

173
00:08:49.050 --> 00:08:52.730
and I'm first gonna check to see if there are any posts.

174
00:08:52.730 --> 00:08:57.730
So I'm gonna say if props dot posts and, we know we always

175
00:08:59.440 --> 00:09:03.200
got posts so, we're always gonna have that because

176
00:09:03.200 --> 00:09:05.130
that is a required property.

177
00:09:05.130 --> 00:09:09.810
So I'm just gonna say if our length is greater than zero

178
00:09:09.810 --> 00:09:12.680
that's when we're gonna want to render something.

179
00:09:12.680 --> 00:09:16.700
I'll just add a to do here, and then if not

180
00:09:16.700 --> 00:09:19.050
then I wanna return null.

181
00:09:19.050 --> 00:09:21.460
So this is going to give us the ability

182
00:09:21.460 --> 00:09:25.660
to if we get any posts that are empty, or we get,

183
00:09:25.660 --> 00:09:28.900
take for example, a search that doesn't have any posts

184
00:09:28.900 --> 00:09:31.050
then we wanna return null.

185
00:09:31.050 --> 00:09:34.040
We don't want to try to iterate over these items

186
00:09:34.040 --> 00:09:36.470
or else we could run into some type of bug.

187
00:09:36.470 --> 00:09:39.500
So I'm gonna get rid of that and, now,

188
00:09:39.500 --> 00:09:43.320
I'm gonna take, where it says props, I'm gonna take that

189
00:09:43.320 --> 00:09:47.500
and I'm gonna cut it all the way down to the parens

190
00:09:47.500 --> 00:09:50.650
and I'm gonna say if we do have more,

191
00:09:50.650 --> 00:09:54.820
or if we do have any posts that length is greater

192
00:09:54.820 --> 00:09:59.820
than zero then I want you to return the props dot posts

193
00:10:00.480 --> 00:10:03.050
dot map and so then it will iterate

194
00:10:03.050 --> 00:10:04.650
through each one of those.

195
00:10:04.650 --> 00:10:08.083
So let's call postsRenderer and let's hit save

196
00:10:11.490 --> 00:10:13.250
and see if this works.

197
00:10:13.250 --> 00:10:14.160
And there ya go.

198
00:10:14.160 --> 00:10:15.963
That is working perfectly.

199
00:10:16.984 --> 00:10:18.900
So we don't have any warnings, everything there is looking

200
00:10:18.900 --> 00:10:22.200
really nice and sharp and so our FeedScreen

201
00:10:22.200 --> 00:10:25.500
has really been streamlined and I like this because

202
00:10:25.500 --> 00:10:29.100
now the FeedScreen it's not doing too much.

203
00:10:29.100 --> 00:10:32.050
It's only in charge of going and getting posts

204
00:10:32.050 --> 00:10:36.000
and then, once it gets em, it sends it to this PostList

205
00:10:36.000 --> 00:10:40.830
component and then that is what is in charge of having

206
00:10:40.830 --> 00:10:44.930
the ScrollView, the styles, iterating over the collection,

207
00:10:44.930 --> 00:10:47.190
checking to make sure there are posts.

208
00:10:47.190 --> 00:10:51.270
All of that now is in one spot, and so now,

209
00:10:51.270 --> 00:10:53.700
the whole reason why we did that, was because

210
00:10:53.700 --> 00:10:57.160
we wanted the ability to call this from the SearchScreen.

211
00:10:57.160 --> 00:10:59.260
So let's see if we can do that now.

212
00:10:59.260 --> 00:11:01.100
So we have our search bar.

213
00:11:01.100 --> 00:11:04.230
I'm gonna get rid of where it says search screen text here.

214
00:11:04.230 --> 00:11:09.230
And let's go to our search and let's call that function.

215
00:11:09.480 --> 00:11:14.480
So I'm gonna call PostList, there you go PostList,

216
00:11:15.650 --> 00:11:18.480
just like that and we need to call it.

217
00:11:18.480 --> 00:11:22.150
Now we also need to store that value, so let's go do that.

218
00:11:22.150 --> 00:11:25.550
Inside of our response here we're going to create

219
00:11:25.550 --> 00:11:28.530
a new piece of state, so let's just call it posts,

220
00:11:28.530 --> 00:11:30.420
cause I think that makes the most sense.

221
00:11:30.420 --> 00:11:33.280
This is our list of posts and we need the ability

222
00:11:33.280 --> 00:11:37.110
to call posts and then set posts.

223
00:11:37.110 --> 00:11:39.150
And that's gonna be of type array

224
00:11:39.150 --> 00:11:41.990
and that's gonna start off with a default array.

225
00:11:41.990 --> 00:11:45.550
So when we get those back, right here,

226
00:11:45.550 --> 00:11:49.550
I'm going to say setPosts and then that's gonna be

227
00:11:49.550 --> 00:11:50.467
responsedata dot nemipediaposts, not queries, posts

228
00:11:56.450 --> 00:11:57.563
just like that.

229
00:11:58.500 --> 00:12:02.030
And then we also need to pass in the posts

230
00:12:02.030 --> 00:12:03.690
and then the navigate function.

231
00:12:03.690 --> 00:12:07.010
So lets do that, so pass in the props

232
00:12:07.010 --> 00:12:10.880
and then let's also pass in navigate

233
00:12:10.880 --> 00:12:13.660
and we can get access to that by just following

234
00:12:13.660 --> 00:12:15.270
what we have right up here.

235
00:12:15.270 --> 00:12:20.270
So we have our props dot navigation dot navigate.

236
00:12:22.342 --> 00:12:26.380
Hit save and everything there should be working.

237
00:12:26.380 --> 00:12:27.930
Okay, this is the moment of truth.

238
00:12:27.930 --> 00:12:30.790
Let's see if we were able to recreate,

239
00:12:30.790 --> 00:12:34.710
in less that a minute, the ability to render posts

240
00:12:34.710 --> 00:12:35.590
on the screen.

241
00:12:35.590 --> 00:12:37.810
So I'm going to search for something.

242
00:12:37.810 --> 00:12:40.690
We know we have some programming posts,

243
00:12:40.690 --> 00:12:43.840
and if I hit return right here, look at that.

244
00:12:43.840 --> 00:12:47.940
We have a fully functional result set

245
00:12:47.940 --> 00:12:52.390
and we didn't really do any work except three lines of code

246
00:12:52.390 --> 00:12:53.570
in our SearchScreen.

247
00:12:53.570 --> 00:12:57.650
That really kind of speaks to the power and benefit

248
00:12:57.650 --> 00:13:00.888
of component driven architecture, where you can create

249
00:13:00.888 --> 00:13:05.800
these components that manage just a few responsibilities

250
00:13:05.800 --> 00:13:09.740
but those can be called form any part of the application

251
00:13:09.740 --> 00:13:14.270
and then can share some type of render function

252
00:13:14.270 --> 00:13:17.610
or some custom type of behavior, and in our case

253
00:13:17.610 --> 00:13:21.530
we're able to have our main FeedScreen,

254
00:13:21.530 --> 00:13:25.620
and the our SearchScreen, have the same type

255
00:13:25.620 --> 00:13:28.580
of look and feel without us having to go

256
00:13:28.580 --> 00:13:30.100
and duplicate all that code.

257
00:13:30.100 --> 00:13:34.350
So if we hadn't of created this PostList component,

258
00:13:34.350 --> 00:13:37.770
we would have needed to go and recreate

259
00:13:37.770 --> 00:13:39.840
everything right here.

260
00:13:39.840 --> 00:13:41.580
We would have needed to build out

261
00:13:42.891 --> 00:13:44.130
a handleItemPress function.

262
00:13:44.130 --> 00:13:47.250
We would have needed to build out a Render function

263
00:13:47.250 --> 00:13:48.920
and then call a ScrollView.

264
00:13:48.920 --> 00:13:52.557
And then imagine a scenario where we're told,

265
00:13:52.557 --> 00:13:55.010
"Oh, you need to go change a few of those things."

266
00:13:55.010 --> 00:13:58.660
Maybe we do want to add a user or we want to make

267
00:13:58.660 --> 00:14:01.240
some like button, or something like that.

268
00:14:01.240 --> 00:14:02.520
Then what you'd have to do,

269
00:14:02.520 --> 00:14:05.410
is you'd have to go and change multiple spots.

270
00:14:05.410 --> 00:14:09.500
You'd have to go and find every spot you had created

271
00:14:09.500 --> 00:14:12.360
that type of behavior in, and then you'd have to go

272
00:14:12.360 --> 00:14:14.980
and duplicate it all again.

273
00:14:14.980 --> 00:14:17.480
It really creates a nightmare to maintain,

274
00:14:17.480 --> 00:14:20.480
and so by refactoring that out now,

275
00:14:20.480 --> 00:14:23.990
now our SearchScreen and our FeedScreen

276
00:14:23.990 --> 00:14:28.270
simply have a one line call to that list,

277
00:14:28.270 --> 00:14:30.900
and now if any changes ever have to get made

278
00:14:30.900 --> 00:14:33.160
they can all happen in one spot.

279
00:14:33.160 --> 00:14:35.340
So this is definitely a best practice

280
00:14:35.340 --> 00:14:36.630
and it's also really cool to see.

281
00:14:36.630 --> 00:14:39.150
I love doing those type of refactors,

282
00:14:39.150 --> 00:14:42.180
where we're able to clean up components

283
00:14:42.180 --> 00:14:45.370
and create dedicated ones to manage

284
00:14:45.370 --> 00:14:48.913
just a more specific type of responsibility.

Resources