Thoughts on Components and stuff
TLDR: Create small shared granular components for everything, and a "view" is just an ordered collection of components.
Warning: this is rambly and mostly a brain dump. Read on...
Components. They are so hot right now. So hot. Like all the #hotness. They are flooding twitter, bouncing off the walls of board rooms, being parroted by managers, and shot down/hyped up by developers. But what are they really? What does it really mean to embrace components in development?
So let’s get this out of the way first: Components are not a silver bullet, they will not make your code awesome. They also are nothing new.
For instance a select box, is a component. No I don’t mean you can create a select box that is wrapped in a component. I mean it is a component. It has an API that it exposes to developers, it has default behavior and appearance. It’s a component. This helps me understand what components really are. It helps me see that a component is a focused user interaction. They can be composed of data, aesthetics, behaviors, etc. but fundamentally a good component is a building block.
As tempting as it is to see a component that lays down a massive complicated interaction, that is also a terrible idea. But man does it demo well. As an example, I was once at a conference (NG-conf) and some presenters demoed the work they had done to create an Angular directive that included all the controls for a quadcopter. Yep. (Side note... components and the concepts of componentization can be implemented in any framework or language. At least any I can think of) This is a terrible idea even for a demo. Because components should be focused on the smallest interaction possible. High order components can compose these low level components into larger systems.
The difficult part of all this is understanding that most of the things you know about creating applications is wrong. Here comes heavy hitter #1:
Routes don’t matter to your components.
Seriously they don’t matter. Your component doesn’t care about routes. Routes, or views, are merely higher level components composed of components. This is actually the way things work fundamentally in HTML. The html component (<html>) is composed of a collection, or array, of lower level components (<head>, <body>). These in turn are composed of other lower level components. (<ul> components are made up of lots of <li> components). There is an order there, not unlike an array in JS.
These small lower level components are much like Legos. They can be used to build many many different types of things. They have a public API for modifying their appearance and hooking into them (again think Lego blocks here). Because they are focused on relatively specific things you can use them all over the place for all sorts of things!
Heavy hitter #2:
Low level components do one thing only.
This should be fairly quick actually. If your component can be described as doing more then one thing... break it up into smaller components. Building an RTE? It probably needs to be composed of many smaller components like buttons, file uploader, editor, data store, etc. Consider it a smell test if your component is doing multiple things. It might not be a bad thing... but it probably is. It’s like building a lego house out of prebuilt lego walls. Sure it’s fast and looks cool, but what happens when you want to put in a window?
The more granular you can get with your components the more useful and flexible they will be in the future. This seems counterintuitive because they are more purpose built. But so are lego blocks.
Heavy hitter #3:
High level components are dumb.
Logic basically stays out of high level components. They are there to assemble smaller components and allow for them to interact in a cohesive way, but they shouldn’t be doing a whole lot of thinking. If logic is creeping into your high level components then you might want to double check that there isn’t a smaller component in there that needs to be broken up.
Heavy hitter #4:
Everything you will write will be reused by someone.
Probably you. Code accordingly, but don’t abuse the APIs you are creating to make components do things they aren’t designed to do. If it doesn’t do what you want it to create a new one that does.
Last but not least.
Your directory structure should reflect this. Since everything is a component that leads to a very flat directory structure where everything lives in the components directory. Each component should be its own directory, and inside should be everything about that component. Tests go in there. Styles go in there. DOM goes in there. JS goes in there. This will help when you start sharing things between projects. This will also make it super easy to turn things into npm/bower modules. And it will make it easy for you to maintain focused context while coding. Win win win.
Some will argue this leads to chaos in that folder... but if you name your components according to what they do you’ll be fine. I promise. It will actually be easier to find things because you will only have one place to look.