Controllers have been used to represent the different pages of an app for a while now. For example, a shopping site might have a login controller, a products controller, and a checkout controller.
Components existed alongside these controllers, representing reusable functionality. For example, the shopping site might have a product view component showing a photo, description, and price of merchandise, which can be re-used in the product and checkout pages. This type of “widget component” is very useful for organizing code and functionality.
Some other examples of widget components might be a 1-5 star movie rater, a date picker, and a type-ahead search box. These exist as useful, bite-sized pieces of code that group together views and logic for code re-use, organization, and repeatable user experiences. This kind of component is often talked about as a demonstration of what a component is. But with the controller pattern going away, these widget-style components are only half of component-based architecture.
Good widgets are simple to use, focus on doing one thing well, and use events to communicate, while widget patterns to avoid include mutating data that is passed in and grouping too much functionality together.
Here are some examples:
Structural components are not designed to be reused throughout your SPA as a widget component would be. They are different from controllers, too. Whereas controllers controlled an entire page at a time, structural components only represent a bite-sized piece of the page.
Instead, several structural components can be composed together into a component tree to represent the entire page. I’ve recommended it before–the Thinking in React article demonstrates how structural components can be used to build up an application.
In our earlier example, the products component might contain a search component for searching components, and a product grid component for displaying products. Each product in the grid could be its own component, and so on.
Using Component-Based Architecture
Similar to the controller architecture, when using a component architecture, it’s best to avoid storing business logic in widgets, including most API requests (exceptions can be made for fetching lists of data to display in drop-downs). Instead, keep your business logic in the structural component where they seem to best fit. For API requests, a good guideline is the most specific place that can get the data everywhere it needs to go.
What’s the gain? First, SPAs that focus on component architecture won’t get left behind as frameworks transition away from controllers. And secondly, because controllers can get bloated and there’s no way to break them down (except with structural components), it’s not a sustainable architecture for a long-term large application. It’s a place where a lot of code mess has been introduced in legacy SPAs.
By representing your application as a tree of structural and widget components, it’s easier to maintain and take forward with smaller, cleaner pieces of code.