Jake Worth

Jake Worth

What Are the Tradeoffs of Passing Objects as React Props?

Published: June 27, 2022 • Updated: January 19, 2023 2 min read

  • react

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?

  • The initials? ("JW")
  • The first and last names of the user? ("Jake Worth")
  • Or should we pass the entire user object? (user)

Let’s consider the tradeoffs of each.

Passing Just the Initials

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.”

Passing the Names

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.

Passing the Entire Object

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.

Passing More Than One of These

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.

So, Which Should I Choose?

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.

Conclusion

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!


Join 100+ engineers who subscribe for advice, commentary, and technical deep-dives into the world of software.