Reader small image

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

Product typeBook
Published inMay 2022
Reading LevelIntermediate
PublisherPackt
ISBN-139781803231280
Edition4th Edition
Languages
Right arrow
Authors (3):
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

Roy Derks
Roy Derks
author image
Roy Derks

Roy Derks is a serial start-up CTO, international speaker, and author from the Netherlands. He has been working with React, React Native, and GraphQL since 2016. You might know him from the book “React Projects – Second Edition”, which was released by Packt earlier this year. Over the last few years, he has inspired tens of thousands of developers worldwide through his talks, books, workshops, and courses.
Read more about Roy Derks

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

View More author details
Right arrow

Chapter 6: Crafting Reusable Components

The focus 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...

Technical requirements

You can find the code files for this chapter on GitHub at https://github.com/PacktPublishing/React-and-React-Native-4th-Edition/tree/main/Chapter06.

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 about HTML...

The difficulty 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. The bigger 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 to learn and use. Component communication essentially means that the state of...

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.

Note

Render props aren't a React 16 feature. It's a technique whose popularity increase coincided with the release of React 16. It's an officially recognized way to deal with dependency and substitution...

Refactoring class components using hooks

Prior to the addition of hooks to React, we would often end up using class-based components just because the component had state data to maintain. Hooks exist so that you can implement React components using regular functions and still have access to the React APIs that you used to access through class attributes and methods. In this section, we'll rewrite the MyFeature component so that it's a function and it uses the useState() hook.

First, let's take a look at the functional version of MyFeature:

function MyFeature({ addArticle, articleList }) {
  const [articles, setArticles] = React.useState([
    {
      id: id.next(),
      title: "Article 1",
      summary: "Article 1 Summary",
      display: "none",
    },
  ...

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:

...

Feature components and utility components

In the monolithic component example, you started off with a single component that was entirely focused on a feature. This means that the component has very little utility elsewhere in the application.

The reason for this is that top-level components deal with the application state. Stateful components are difficult to use in any other context. As you refactored the monolithic feature component, you created new components that moved further away from the data. The general rule is that the further your components move from stateful data, the more utility they have because their property values could be passed in from anywhere in the application.

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 React component life cycle. This is an especially relevant topic for implementing container components.

...

Further reading

Visit the following links for more information:

lock icon
The rest of the chapter is locked
You have been reading a chapter from
React and React Native - Fourth Edition
Published in: May 2022Publisher: PacktISBN-13: 9781803231280
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 (3)

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

author image
Roy Derks

Roy Derks is a serial start-up CTO, international speaker, and author from the Netherlands. He has been working with React, React Native, and GraphQL since 2016. You might know him from the book “React Projects – Second Edition”, which was released by Packt earlier this year. Over the last few years, he has inspired tens of thousands of developers worldwide through his talks, books, workshops, and courses.
Read more about Roy Derks

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