···11---
22title: CRC Cards as training material
33layout: post
44-date: 2022-12-03
44+date: 2022-12-24
55draft: true
66---
77···8181 <Title title={i18n('bookmark.user_bookmarks')} />
8282 {isLoading
8383 ? <TilesSkeleton animation={tilesAnimation} numberOfTiles={16} />
8484- : <BookmarkItem
8585- key={bookmark.id}
8686- data={bookmark}
8787- />}
8484+ : <Bookmarks data={bookmarks} />}
88858986 <PrimaryButton
9087 text={i18n('bookmark.add_bookmark')}
···134131// ...
135132```
136133137137-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} />.
134134+Only the `user id` is necessary, why not just give the user id instead of the whole object? That will be our first simplification .
138135139136> ℹ️ We'll simplify at the very end, once we'll be finished with our CRC card.
140137···161158 "Display user bookmarks",
162159 "fetching bookmarks",
163160 "handling async processes (loading and error state)",
164164- "handling add bookmark modal visibility",
161161+ "display 'add bookmark' button",
162162+ "handling 'add bookmark' modal visibility",
165163 ]}
166164 collaborators={["Home.tsx"]}
167165/>
168166169167### The ugly responsability
170168171171-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} />
169169+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.
172170173171```tsx
174172const tilesAnimation = gsap.to({
···188186 "Display user bookmarks",
189187 "fetching bookmarks",
190188 "handling async processes (loading, error)",
191191- "handling add bookmark modal visibility",
189189+ "display 'add bookmark' button",
190190+ "handling 'add bookmark' modal visibility",
191191+ "Defining TilesSkeleton animation",
192192+ ]}
193193+ collaborators={["Home.tsx"]}
194194+/>
195195+196196+## What do we keep?
197197+198198+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.
199199+200200+> `UserBookmarks` retrieve and handle the _user_ bookmarks with an additional button to add it.
201201+202202+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.
203203+204204+Let's display the responsabilities that doesn't quite respect the definition.
205205+206206+<CrcCard
207207+ name="UserBookmarks"
208208+ responsabilities={[
209209+ "Display user bookmarks",
210210+ "~ fetching bookmarks",
211211+ "handling async processes (loading, error)",
212212+ "display 'add bookmark' button",
213213+ "⚠️ handling 'add bookmark' modal visibility",
192214 "⚠️ Defining TilesSkeleton animation",
193215 ]}
194216 collaborators={["Home.tsx"]}
195217/>
196218219219+And here its final CRC Card:
220220+221221+<CrcCard
222222+ name="UserBookmarks"
223223+ responsabilities={[
224224+ "Retrieve bookmarks",
225225+ "handling async processes (loading, error)",
226226+ "display user bookmarks",
227227+ "display 'add bookmark' button",
228228+ ]}
229229+ collaborators={["Home.tsx"]}
230230+/>
231231+197232## Simplification
198233199199-Once we said all that, let's relook our component.
234234+Once we said all that, let's relook our component: less responsability and less hooks.
200235201201-### <OrderTag order={1} /> only necessary prop
236236+### Has only necessary prop
202237203238```tsx
204239interface Props {
···218253// ...
219254```
220255221221-### <OrderTag order={2} /> not responsible of child's animation
256256+### Is not responsible of child's animation
222257223258```tsx
224259// removing the magic number at the same time
225260<TilesSkeleton numberOfTiles={MAXIMUM_BOOKMARKS} />
226261```
262262+263263+### Does not fetch itself user bookmarks
264264+265265+```tsx
266266+// ...
267267+const { bookmarks, refetch, isLoading, error } = useUserBookmarksQuery({
268268+ userId,
269269+})
270270+// ...
271271+```
272272+273273+### Does not handle `AddBookmark` modal
274274+275275+Here we only remove code
276276+277277+## The final version
278278+279279+```tsx
280280+interface Props {
281281+ user: User
282282+}
283283+284284+export const UserBookmarks: FunctionComponent<Props> = ({ user }) => {
285285+ const { bookmarks, refetch, isLoading, error } = useUserBookmarksQuery({
286286+ userId,
287287+ })
288288+289289+ return <div className="user-bookmarks">
290290+ <Title title={i18n('bookmark.user_bookmarks')} />
291291+ {isError
292292+ ? <ErrorMessage>An error occured</ErrorMessage>
293293+ : isLoading
294294+ ? <TilesSkeleton numberOfTiles={16} />
295295+ : <Bookmarks bookmarks={bookmarks} />}
296296+297297+ <AddBookmarkButton onNewBookmark={() => refetch())} />
298298+ </div>
299299+}
300300+```
301301+302302+## Final thought
303303+304304+What a
227305228306## Playground
229307