Chapter 9. Thinking of Plugins
In the previous chapter, we looked at a couple of design patterns that we could use to build our applications. There are reasons for and against the use of Flux and Redux, but they generally improve the structure of React applications.
A good structure is essential for any large-scale application. Cobbling things together may work for small experiments, but design patterns are an integral part of maintaining anything larger. They do not say much in the way of creating extendable components, though. In this chapter, we're going to look at a few ways that we can use to make our components extendable by replacing them, injecting functionality, and composing interfaces from dynamic lists of components.
We're going to review a few related software design concepts and take a look at how they can assist us (and others) when we want to replace parts of our application with modified components and alternative implementations.
Dependency injection and service location
Dependency injection and service location are interesting concepts that are not limited to React development. To really understand them, let's move away from components for a while. For a moment, imagine that we wanted to create a sitemap. To do this, we could perhaps use code resembling the following code:
In this example, createSitemap
has two dependencies. Firstly, we fetch pages from backend
. This is a kind of global storage object. We used something similar to this when we looked at the Flux architecture.
The second dependency is to the SitemapFormatter
implementation...
Another method to create more pluggable components is to expose (and act on) event callbacks. We saw something similar already, but let's take a look at this anyway. Suppose we have a PageEditorComponent
class, as follows:
Stores, reducers, and components
Building on these concepts, the final thing that we want you to look at is how this all fits together inside a Redux architecture.
Note
If you've skipped ahead to this chapter, make sure that you have a firm understanding of Redux by reading the previous chapter.
Let's begin with a PageComponent
class (for individual pages, in a list):
In this chapter, we looked at a few methods that we could use to make our components (and general architecture) open to extension without requiring core modification. There's a lot to take in here and not nearly enough community standardization for this to be the final word on pluggable components. Hopefully, there's enough here for you to design the right plugin architecture for your application.
In the next chapter, we will look at various ways to test the components and classes that we've built so far. We'll continue to see the benefits of things, such as dependency injection and service location, while also learning about a few new tools.