Reader small image

You're reading from  React and React Native - Fifth Edition

Product typeBook
Published inApr 2024
Reading LevelBeginner
PublisherPackt
ISBN-139781805127307
Edition5th Edition
Languages
Tools
Right arrow
Authors (2):
Mikhail Sakhniuk
Mikhail Sakhniuk
author image
Mikhail Sakhniuk

Mikhail Sakhniuk is Software Engineer with high proficiency in JavaScript, React and React Native. He has more than 5 years of experience in developing web and mobile applications. He has worked for startups, fintech companies, and product companies with more than 20 million users. Currently, Mikhail is working at Miro as a Frontend Engineer. In addition, he owns and maintains a few open-source projects. He also shares his experience and knowledge through books and articles.
Read more about Mikhail Sakhniuk

Adam Boduch
Adam Boduch
author image
Adam Boduch

Adam Boduch has been involved in large-scale JavaScript development for nearly 15 years. Before moving to the frontend, he worked on several large-scale cloud computing products using Python and Linux. No stranger to complexity, Adam has practical experience with real-world software systems and the scaling challenges they pose.
Read more about Adam Boduch

View More author details
Right arrow

Crafting Reusable Components

The aim of this chapter is to show you how to implement React components that serve more than just one purpose. After reading this chapter, you’ll feel confident about how to compose application features.

The chapter starts with a brief look at HTML elements and how they work in terms of helping to implement features versus having a high level of utility. Then, you’ll see the implementation of a monolithic component and discover the issues that it will cause down the road. The next section is devoted to re-implementing the monolithic component in such a way that the feature is composed of smaller components.

Finally, the chapter ends with a discussion of rendering trees of React components and gives you some tips on how to avoid introducing too much complexity as a result of decomposing components. I’ll close the final section by reiterating the concept of high-level feature components versus utility components.

The following...

Technical requirements

You can find the code files for this chapter on GitHub at https://github.com/PacktPublishing/React-and-React-Native-5E/tree/main/Chapter05.

Reusable HTML elements

Let’s think about HTML elements for a moment. Depending on the type of HTML element, it’s either feature-centric or utility-centric. Utility-centric HTML elements are more reusable than feature-centric HTML elements. For example, consider the <section> element. This is a generic element that can be used just about anywhere but its primary purpose is to compose the structural aspects of a feature: the outer shell of the feature and the inner sections of the feature. This is where the <section> element is most useful.

On the other side of the fence, you have elements such as <p>, <span>, and <button>. These elements provide a high level of utility because they’re generic by design. You’re supposed to use <button> elements whenever you have something that’s clickable by the user, resulting in an action. This is a level lower than the concept of a feature.

While it’s easy to talk...

The diffculty with monolithic components

If you could implement just one component for any given feature, it would simplify your job. At the very least, there wouldn’t be many components to maintain, and there wouldn’t be many communication paths for data to flow through because everything would be internal to the component.

However, this idea doesn’t work for a number of reasons. Having monolithic feature components makes it difficult to coordinate any kind of team development effort, such as version control, merge conflicts, and parallel development. The bigger the monolithic components become, the more difficult they are to refactor into something better later on.

There’s also the problem of feature overlap and feature communication. Overlap happens because of similarities between features; it’s unlikely that an application will have a set of features that are completely unique to one another. That would make the application very difficult...

Refactoring component structures

You have a monolithic feature component: now what? Let’s make it better.

In this section, you’ll learn how to take the feature component that you just implemented in the preceding section and split it into more maintainable components. You’ll start with the JSX, as this is probably the best refactor starting point. Then, you’ll implement new components for the feature.

Next, you’ll make these new components functional instead of class-based. Finally, you’ll learn how to use render props to reduce the number of direct component dependencies in your application, and how to remove classes entirely by using hooks to manage state within functional components.

Starting with the JSX

The JSX of any monolithic component is the best starting point for figuring out how to refactor it into smaller components. Let’s visualize the structure of the component that we’re currently refactoring...

Render props

Imagine implementing a feature that is composed of several smaller components, like what you’ve been working on in this chapter. The MyFeature component depends on ArticleList and AddArticle. Now, imagine using MyFeature in different parts of your application where it makes sense to use a different implementation of ArticleList or AddArticle. The fundamental challenge is substituting one component for another.

Render props are a nice way to address this challenge. The idea is that you pass a property to your component whose value is a function that returns a component to render. This way, instead of having the feature component directly depend on its child components, you can configure them as you like; they pass them in as render prop values. Let’s look at an example. Instead of having MyFeature directly depend on AddArticle and ArticleList, you can pass them as render props. Here’s what the MyFeature looks like when it’s using render...

Rendering component trees

Let’s take a moment to reflect on what we’ve accomplished so far in this chapter. The feature component that was once monolithic ended up focusing almost entirely on the state data. It handled the initial state and handled transforming the state and it would handle network requests that fetch state, if there were any. This is a typical container component in a React application, and it’s the starting point for data.

The new components that you implemented to better compose the feature were the recipients of this data. The difference between these components and their container is that they only care about the properties that are passed into them at the time they’re rendered. In other words, they only care about data snapshots at a particular point in time. From here, these components might pass the property data into their own child components as properties. The generic pattern for composing React components is as follows:

...

Summary

This chapter was about avoiding a monolithic component design. However, monoliths are often a necessary starting point in the design of any React component.

You began by learning about how the different HTML elements have varying degrees of utility. Next, you learned about the issues with monolithic React components and walked through the implementation of a monolithic component.

Then, you spent several sections learning how to refactor the monolithic component into a more sustainable design. From this exercise, you learned that container components should only have to think in terms of handling state, while smaller components have more utility because their property values can be passed from anywhere. You also learned that you could use render props for better control over component dependencies and substitution.

In the next chapter, you’ll learn about the component props validation and type checking.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
React and React Native - Fifth Edition
Published in: Apr 2024Publisher: PacktISBN-13: 9781805127307
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Authors (2)

author image
Mikhail Sakhniuk

Mikhail Sakhniuk is Software Engineer with high proficiency in JavaScript, React and React Native. He has more than 5 years of experience in developing web and mobile applications. He has worked for startups, fintech companies, and product companies with more than 20 million users. Currently, Mikhail is working at Miro as a Frontend Engineer. In addition, he owns and maintains a few open-source projects. He also shares his experience and knowledge through books and articles.
Read more about Mikhail Sakhniuk

author image
Adam Boduch

Adam Boduch has been involved in large-scale JavaScript development for nearly 15 years. Before moving to the frontend, he worked on several large-scale cloud computing products using Python and Linux. No stranger to complexity, Adam has practical experience with real-world software systems and the scaling challenges they pose.
Read more about Adam Boduch