Extracting Components

Don’t be afraid to split components into smaller components.

For example, consider this Comment component:

function Comment(props) {

return (

<div className=”Comment”>

<div className=”UserInfo”>

<img className=”Avatar”

src={props.author.avatarUrl}

alt={props.author.name}

/>

<div className=”UserInfo-name”>

{props.author.name}

</div>

</div>

<div className=”Comment-text”>

{props.text}

</div>

<div className=”Comment-date”>

{formatDate(props.date)}

</div>

</div>

);

}

It accepts author (an object), text (a string), and date (a date) as props, and describes a comment on a social media website.

This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let’s extract a few components from it.

First, we will extract Avatar:

function Avatar(props) {

return (

<img className=”Avatar”

src={props.user.avatarUrl}

alt={props.user.name}

/>

);

}

The Avatar doesn’t need to know that it is being rendered inside a Comment. This is why we have given its prop a more generic name: user rather than author.

We recommend naming props from the component’s own point of view rather than the context in which it is being used.

We can now simplify Comment a tiny bit:

function Comment(props) {

return (

<div className=”Comment”>

<div className=”UserInfo”>

<Avatar user={props.author} />

<div className=”UserInfo-name”>

{props.author.name}

</div>

</div>

<div className=”Comment-text”>

{props.text}

</div>

<div className=”Comment-date”>

{formatDate(props.date)}

</div>

</div>

);

}

Next, we will extract a UserInfo component that renders an Avatar next to the user’s name:

function UserInfo(props) {

return (

<div className=”UserInfo”>

<Avatar user={props.user} />

<div className=”UserInfo-name”>

{props.user.name}

</div>

</div>

);

}

This lets us simplify Comment even further:

function Comment(props) {

return (

<div className=”Comment”>

<UserInfo user={props.author} />

<div className=”Comment-text”>

{props.text}

</div>

<div className=”Comment-date”>

{formatDate(props.date)}

</div>

</div>

);

}

Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times (Button, Panel, Avatar), or is complex enough on its own (App, FeedStory, Comment), it is a good candidate to be a reusable component.

Get industry recognized certification – Contact us

Menu