Often, when you start the development of an application, you can get in trouble trying to understand how to organize your components.
In this post...
For further actions, you may consider blocking this person and/or reporting abuse
Atomic design didn't work for me actually when using it with React. It makes finding the components harder than just using a flat, or feature-based structure. Let me give an example:
We have a
Button
component. It's a dumb component doing nothing, so we probably put this into Atoms. Now, I want to have anIconButton
, which usesButton
, so we'll put it to Molecules. Next, let's say we have aSubscriptionButton
, which opens a newsletter subscription modal - this is a lot of logic, so we'll put it to Organisms. Now, it was not obvious for me or my co-workers (and especially newcomers) where should we look for the specific component. It very quickly became a mess.IMO a lot clearer is a structure based on features. Basing on the earlier example,
Button
andIconButtons
would be just Components (where all reusable, dumb components land), andSubscriptionButton
would be somewhere in aSubscriptions
folder, along with things likeSubscriptionModal
,SubscriptionModalCloseButton
etc.Hi Jakub,
thank you for your comment: I really appreciate it!
I'm not saying that the Atomic Design is the panacea to all evils (it has some limits of course). What I wrote is that it can help you to think in reusable components way.
I think this approach is not correct: the
SubscriptionButton
shouldn't have any kind of logic, but it should have atrigger
prop to be used for launching events (in your case opening a Modal).The
SubscriptionModal
should be a different component and, using React, the best scenario could be something like:I would put the logic part in the component which wrap both
SubscriptionButton
andSubscriptionModal
.What do you think? 🙂
I agree! I think that I didn't use a proper example for this 😄 I used Atomic Design in a project a few years ago and I forgot already about the specific cases where we struggled with using it.
I don't say it's a bad pattern, it just didn't work for me for some reason 😄
Oh, forgot to mention: your article is great!
While I am a fan of applying atomic design to components, I have to disagree with you about it helping with code organisation - at least in the manner you propose.
At first it does help, when the application is small. However, down the road - when the application is larger and you get back to a feature after 6 months - not having the related components together creates mental overhead.
For our next project we will keep using atomic design, but we're looking into better ways to organise our components. We'll probably go back to feature folders and depending on the size of the feature the components will be either prefixed or put in subfolders according to their atomic type.
An added benefit is that it's a step closer to breaking a feature out into a separate npm package.
Is there a particular reason for making a text component?
35 lines of code just to render a
<p>
or<label>
seems incredibly overcomplicated.Hi Janus,
thank you for your comment: I really appreciate it!
I can get your perplexity about the "overengineering" of the
Text
component.Let me try to clarify your doubts.
The
Text
component in this context has too much implementation, it's true. Just two things:Having a component like this can bring some advantages.
Consistency
You have to think the this component is meant to be used and used and used... If you need to use it several times, then you must a have a consinstent component with the same size, the same font-family, the same color and so on. It's really hard to have this kind of consistency without using a component.
Let me give you one example:
This means that, when you need to write something, to have texts which are consinstent you have to apply the same classes. Everytime. And this is not a smart approach neither stable, because it's very buggy (try to imagine what could happen writing the
weight-medium
class 50 times).Automatic updates
Futhermore, with a reusable component, if you want to change a class or a default value, you just need to modify the component itself and the changes will be automatically reflected everywhere.
Having reusable components is very useful, especially in design systems.
Anyway, I want to give you a suggestion: do not put your focus on the
Text
's implementation; put it on the usage. The implementation is made only once, but the usage might be done n times.I'm sorry, but I don't think your example makes sense.
Of course, reusable components are useful. Very much so.
But you are talking about making an entire component only for text elements.
In your post, you describe making a molecule that combines a label with an input. That's fine.
But you gain nothing from having the label as a generic text component with
type=label
over just writing<label class="input-field__label"/>
.Everything you said about changing the label in one place still applies.
And if you want to have consistent
<p>'s
you put a standard style for paragraphs in your stylesheet.Your long example of five different classes implies that a
<span>
could have other classes. That would be exactly the same with a text componenttype=span
.So again, it's not actually simpler.
But of course, you should write your code however you see fit :-)
And that day you'll have to search and replace it in the whole code. ;)
How would you bind the events which are concerning the input fields? Would you bubble up all the events?
Or let's say I want to dispatch an action to my reducer. I should do this from my smart component while the Button (dumb component) is a child 3 levels bellow. So, when I click this button, should I have an onClick event that will go from the atom and then to the molecule and then to the organism and then to the page? Or how would you solve this?
What if one day You will decide to use some Bootstrap component instead of simple input? Or some other component library like Vuetify? Having this seperation gives You a freedom to do it very fast and easy. This is the point of having own abstraction.
By the way iconButton could be considered as molecule which cosists of button atom and icon atom ;)
Naming stuff well is hard and if You can put some system in place for that it can payoff in a large long term project. It is very easy to go wrong with component spliting. I have seen it many times. So if you think that things will never change think twice.
Hello, first of all thank you for this beautiful article. It is a method I use frequently. But there are a few questions in my mind I will be glad if you answer my questions. When we divide the components as you mentioned, it would be more correct to write the css of the element in the related component. Is it in our global css file or in direct component? Like style-scoped. And if we do it this way, for example, if I will use the button component in three places on the home page, will it be duplicated three times? Thank you.
Thank you for sharing the good post
In app.vue, how are we going to create 2 way binding between the input data inside the component with data declared in app.vue?