React component patterns help us create reusable and extendable components that provide some inversion of control to their parent
Here's a thread of 5️⃣ such patterns
But first let's start with a vanilla <Button> component with "normal" props & how it's used
/thread 🧵👇🏾
1️⃣ Placeholder props
The placeholder props pattern allows the shared component to control its layout & any logic, but give some control to the parent for the display
For our Button comp, the `startIcon` & `endIcon` props can be <svg>, <img> or even other React components
🧵👇🏾
2️⃣ Polymorphic components
The polymorphic component pattern comes in handy when we need flexibility on the rendered element
For semantic HTML or a11y reasons we may need to change the root element. We can even pass another component for the `as` prop (react-router <Link>)
🧵👇🏾
3️⃣ Controlled components
The controlled components pattern gives parents flexible control over the shared component's UI logic. The passed in props can make it "controlled" or "uncontrolled"
(see blog post below for more details)
🧵👇🏾
4️⃣ Render props
The render prop pattern comes in handy when a shared component needs to control layout of any common UI and stateful logic, but the visual look-and-feel is left to the parent component
Render props are typically named `render` or use the `children` prop
🧵👇🏾
5️⃣ Compound components
When we require full customization of multiple interconnected components, the compound components pattern is very helpful
However it's more complex to implement. IMO it makes the complex use case easier but makes the simple use case more complex
🧵👇🏾
I can only explain so much in 280 characters, so if you wanna learn more I suggest you check out the blog post with all the explanations
What other React component patterns do you use often? 🤔
What are some situations for when we can use the `useCallback()` & `useMemo()` Hooks in React components?
Well, one case where we need `useCallback()` is when we call a helper function w/in `useEffect()`, so we need "referential equality" to include it in deps
/thread 🧵👇🏾
I also use `useCallback()` by default when returning a function from a custom Hook cuz I dunno how that function will be used w/in host components
`useCallback()` gives a stable function reference similar to the updater func from `useState()` (the 2nd array element)
🧵👇🏾
The `useMemo()` Hook is similar to `useCallback()` except that it memoizes any value not just functions
So I use `useMemo()` in the same situations: when I have a derived object/array that's used in the deps of `useEffect()`
The .reduce() method is maybe the most powerful, yet least understood array method. It basically allows us to transform an array into... nearly anything else
Let's re-implement 1️⃣0️⃣ lodash functions to learn more about how for examples on how .reduce works
/thread 👇🏾🧵
1️⃣ sum()
ℹ️ Computes the sum of the values in an array
The function is called a "reducer" & the 2nd param is our initial value
The 1st arg of the reducer is the "accumulator" (the value we're building up). The 2nd is the current array element in the iteration
/thread 👇🏾🧵
2️⃣ countBy()
ℹ️ Creates an object w/ keys that are the array elements and values that are their counts
Here we're turning an array into an object
(can't forget to return the object we're accumulating!)
Here is a quick React custom Hook that supports copying text to the system clipboard. It also returns a copied/failed status that can be reflected in the UI
(I remember the days when we could only do this w/ Flash 😭)
more details in the thread 🧵👇🏾
useCopyToClipboard returns a copy function that the UI calls when the user wants to copy the text (likely a button click). It updates the status based on the success/failure of writing to the clipboard
It uses useCallback to ensure a stable function reference
🧵👇🏾
It also uses useEffect to set a timeout that will reset the status after a specified amount of time. This basically makes the status fleeting, which is a typical user experience