Published: June 27, 2022 • Updated: January 19, 2023 • 2 min read
A common React pattern is to pass an object as a prop. Consider a user avatar component that shows the user’s initials. You might see one in the upper right of your screen right now.
What pieces of a user model should we pass to an Avatar
component to achieve
this?
"JW"
)"Jake Worth"
)user
)Let’s consider the tradeoffs of each.
We could pass just the initials.
<Avatar
initials={user.firstName[0] + user.lastName[0]}
/>
The advantage of this approach is that the component gets what it needs– the initials– and nothing else. It lets the component be dumb, saying: “I receive initials, which I know nothing about, and I show them.”
We could also pass the names that comprise the initials.
<Avatar
firstName={user.firstName}
lastName={user.lastName}
/>
The advantage of this approach is that we aren’t manipulating user
quite as
much in the parent, and instead sending down what we need to the component and
letting it build the initials.
We could pass the entire object!
<Avatar
user={user}
/>
This approach is potentially forward-thinking. Very often the component will end up needing more pieces of the user, such as a full name to show as a title, a background color that the user has selected, or an image URL. Passing the object could be pragmatic.
We could also pass multiple of these.
<Avatar
initials={user.firstName[0] + user.lastName[0]}
user={user}
/>
Components can drift into this pattern over time, and it’s the indefensible choice in this post. Passing an object and a string derived from it is redundant! It forces both the parent and the child to be smart about the object. We don’t want that.
I’m partial to passing the object. Practically, Avatar
almost always ends up
needing more pieces of the user over time. I think the pragmatic choice is to
concede that from the start and pass the object.
YAGNI (You Aren’t Going to Need It) is the first counterargument, and I’m sympathetic. However, often in production you are going to need it.
Reusability is the second counterargument. What if we want to pass pieces of different kinds of objects to the component? Initials-only supports this– it’s just strings. I think this aspiration is imagined more than it is realized in production code, but it could be the right choice.
Thanks to Gabe Reis who shaped my thinking on this during a year of building frontends together at Hashrocket.
🎉 Update: Adam Young responded to my post! He brought up some excellent points: how initials could be built in the ‘M’ of MVC, why displaying them can be a hard programming problem, and how to do it well.
What are your thoughts on this? Let me know!
Get better at programming by learning with me! Join my 100+ subscribers receiving weekly ideas, creations, and curated resources from across the world of programming.