this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

adding the final version of the CRC post

+90 -12
+90 -12
src/pages/posts/crc-cards-as-training-material.mdx
··· 1 1 --- 2 2 title: CRC Cards as training material 3 3 layout: post 4 - date: 2022-12-03 4 + date: 2022-12-24 5 5 draft: true 6 6 --- 7 7 ··· 81 81 <Title title={i18n('bookmark.user_bookmarks')} /> 82 82 {isLoading 83 83 ? <TilesSkeleton animation={tilesAnimation} numberOfTiles={16} /> 84 - : <BookmarkItem 85 - key={bookmark.id} 86 - data={bookmark} 87 - />} 84 + : <Bookmarks data={bookmarks} />} 88 85 89 86 <PrimaryButton 90 87 text={i18n('bookmark.add_bookmark')} ··· 134 131 // ... 135 132 ``` 136 133 137 - Only the `user id` is necessary, why not just give the user id instead of the whole object? That will be our first simplification <OrderTag order={1} />. 134 + Only the `user id` is necessary, why not just give the user id instead of the whole object? That will be our first simplification . 138 135 139 136 > ℹ️ We'll simplify at the very end, once we'll be finished with our CRC card. 140 137 ··· 161 158 "Display user bookmarks", 162 159 "fetching bookmarks", 163 160 "handling async processes (loading and error state)", 164 - "handling add bookmark modal visibility", 161 + "display 'add bookmark' button", 162 + "handling 'add bookmark' modal visibility", 165 163 ]} 166 164 collaborators={["Home.tsx"]} 167 165 /> 168 166 169 167 ### The ugly responsability 170 168 171 - The main problem I see in the `UserBookmarks` component is not about the component itself, it's more on one of its children: `TilesSkeleton`. It's doing a good job for the user experience but it's asking too much for the parent to be able to use it: `UserBookmarks` doesn't care about animating the skeleton. <OrderTag order={2} /> 169 + The main problem I see in the `UserBookmarks` component is not about the component itself, it's more on one of its children: `TilesSkeleton`. It's doing a good job for the user experience but it's asking too much for the parent to be able to use it: `UserBookmarks` doesn't care about animating the skeleton. 172 170 173 171 ```tsx 174 172 const tilesAnimation = gsap.to({ ··· 188 186 "Display user bookmarks", 189 187 "fetching bookmarks", 190 188 "handling async processes (loading, error)", 191 - "handling add bookmark modal visibility", 189 + "display 'add bookmark' button", 190 + "handling 'add bookmark' modal visibility", 191 + "Defining TilesSkeleton animation", 192 + ]} 193 + collaborators={["Home.tsx"]} 194 + /> 195 + 196 + ## What do we keep? 197 + 198 + Now that we listed the responsabilities, it is time to know what do we want to keep by defining the main responsability of the `UserBookmarks` in one and sentence. 199 + 200 + > `UserBookmarks` retrieve and handle the _user_ bookmarks with an additional button to add it. 201 + 202 + That's it. Having a simple sentence defining what's the component does is the purpose of this exercice. Definetely difficult when we first read it, it is now a pretty concise and acceptable responsability we want `UserBookmarks` to have. 203 + 204 + Let's display the responsabilities that doesn't quite respect the definition. 205 + 206 + <CrcCard 207 + name="UserBookmarks" 208 + responsabilities={[ 209 + "Display user bookmarks", 210 + "~ fetching bookmarks", 211 + "handling async processes (loading, error)", 212 + "display 'add bookmark' button", 213 + "⚠️ handling 'add bookmark' modal visibility", 192 214 "⚠️ Defining TilesSkeleton animation", 193 215 ]} 194 216 collaborators={["Home.tsx"]} 195 217 /> 196 218 219 + And here its final CRC Card: 220 + 221 + <CrcCard 222 + name="UserBookmarks" 223 + responsabilities={[ 224 + "Retrieve bookmarks", 225 + "handling async processes (loading, error)", 226 + "display user bookmarks", 227 + "display 'add bookmark' button", 228 + ]} 229 + collaborators={["Home.tsx"]} 230 + /> 231 + 197 232 ## Simplification 198 233 199 - Once we said all that, let's relook our component. 234 + Once we said all that, let's relook our component: less responsability and less hooks. 200 235 201 - ### <OrderTag order={1} /> only necessary prop 236 + ### Has only necessary prop 202 237 203 238 ```tsx 204 239 interface Props { ··· 218 253 // ... 219 254 ``` 220 255 221 - ### <OrderTag order={2} /> not responsible of child's animation 256 + ### Is not responsible of child's animation 222 257 223 258 ```tsx 224 259 // removing the magic number at the same time 225 260 <TilesSkeleton numberOfTiles={MAXIMUM_BOOKMARKS} /> 226 261 ``` 262 + 263 + ### Does not fetch itself user bookmarks 264 + 265 + ```tsx 266 + // ... 267 + const { bookmarks, refetch, isLoading, error } = useUserBookmarksQuery({ 268 + userId, 269 + }) 270 + // ... 271 + ``` 272 + 273 + ### Does not handle `AddBookmark` modal 274 + 275 + Here we only remove code 276 + 277 + ## The final version 278 + 279 + ```tsx 280 + interface Props { 281 + user: User 282 + } 283 + 284 + export const UserBookmarks: FunctionComponent<Props> = ({ user }) => { 285 + const { bookmarks, refetch, isLoading, error } = useUserBookmarksQuery({ 286 + userId, 287 + }) 288 + 289 + return <div className="user-bookmarks"> 290 + <Title title={i18n('bookmark.user_bookmarks')} /> 291 + {isError 292 + ? <ErrorMessage>An error occured</ErrorMessage> 293 + : isLoading 294 + ? <TilesSkeleton numberOfTiles={16} /> 295 + : <Bookmarks bookmarks={bookmarks} />} 296 + 297 + <AddBookmarkButton onNewBookmark={() => refetch())} /> 298 + </div> 299 + } 300 + ``` 301 + 302 + ## Final thought 303 + 304 + What a 227 305 228 306 ## Playground 229 307