loading...
Cover image for ReactJS: Component everything or not?

ReactJS: Component everything or not?

jssantana profile image Jean Santana ・1 min read

Hey devs! Since I started learn ReactJS some questions don't let me sleep. When we should create components?
We should component everything or only if we will use it again in future? What is not a good practice put inside App.js?

Sometimes I put a entire Form inside App.js and I don't know if it is a good practice when use React.

Let me know what you think.

Discussion

pic
Editor guide
 

KISS always, till you need to add complexity.

Do not feel the need to extract everything into a component, yet alone things that won't be reused much.

I tend to build on projects right from the App.js initially, as you mentioned. I only extract once I find myself reusing bits of code (time for a component) or wanting to isolate state and functionality for a larger piece of the app.

 

This is good for a starting point, but it's important to note that large, hard-to-read files you didn't split up, just because you didn't see a case for code reuse, are the opposite of simple.

 

Yep, after a certain point, it's worth extracting simply from a hierarchical and organizational standpoint ✊🏻

 

Hi Jean,
I also very recently started with react js and what I found out was that, it's better to component stuff if u want to reuse it later. Otherwise, I don't see how we get the value out of it.

Also, regarding putting everything inside the app.js, it's best to keep it as clean as possible. So what I did was, I built a pages folder(inside src) and i built the page component, which would have my form or my html elements. Then I would import it as a component in my app.js. Making my app.js much cleaner and easier to look at. This would also make it easier, if ur planning to use routing in the future.

Good Luck !

 

I really like your way!

 

You're thinking about future reuse. That's good. Never know when you might be able to base an entire UI component library on the ones you created for your current project.

 

Good question the answer is much more obvious than you think. If it's a main element on the page then most likely it should be a component. So start with the top level tree and then go down. For example I create a components and pages folder in src. Then I create a component for the header, main and footer because obviously every page is going to have one. Then if you have a hero at the top that is going to be a component too because maybe you want to change it at some point. Forms should definitely be components as well because its a reusable content.

An easy way to figure this out is to go to a website and then look at the page. Work out how you would build it using HTML by using the box model. So what areas will be sections and articles then you will know what should be turned into components.

Alternatively you could print out a webpage and then with a pen or pencil draw boxes around content areas on the page as you would do if you were figuring out how to build it. Those boxes can be reusable components.

 

It's important to note that, in an SPA, the normal page paradigm doesn't necessarily apply. If your header, footer, etc. aren't changing from "page" to "page," it makes more sense to import them once at a higher level than the "pages" of the app (or even just lay them out your index.html in some cases, as separate HTML elements from the div that React loads).

 

I often find myself putting even my router much lower in the hierarchy than I originally anticipated.

 

Start with a single component per page. If your code becomes hard to navigate you can refactor it in to more components.

It's perfectly fine to have a component with 100+ lines of code in it, and it's also fine to have many components in a file.

Good reasons to extract code into a new component:

You need the same thing on multiple pages
If you can extract the markup, state, logic you need without having to add special cases for each page.
Examples: App menu, header, footer, navigation bars.

You want to simplify your page component
You can simplify you page component by extracting some of the code into separate components.

Do this when it feels like it helps and don't be afraid of changing it back later.

Examples: Confirm delete item modal, forms, sections with complex data requirements.

 

Yes, 100+ lines is fine, but much beyond that should be a candidate for splitting up even if only for readability's sake.

 

It really depends on the specific case. If you end up having to switch between 3 different component every time you make a change, it is probably better to keep it as one.

Unless it's variables and methods for that component (which could be evidence that it's time to break out into custom hooks, and/or convert a class component - which I don't write anymore if at all possible - to functional with hooks), I try to keep it on one screen without scrolling as much as possible.

Imports make it easy to follow what is where, and just because you can see it all in one file doesn't mean you're not repeating yourself somewhere else. It's also easier to see exactly what is causing errors when you have them split up.

And as I said about someone else looking toward future reuse, you never know when you might need that exact same component in another project, and your components in your current project could very well be the basis for a whole, independent component library.

 

I always try to solve the problem first and after that, I start to break in smaller components.

I tend to follow the principle of Atomic Design to organize my application.

I keep in mind the following directory organization:

- src/components
      - atoms
      - molecules
      - organisms
      - templates

Atoms

The smaller components commonly are the basis to start more complex ones.

Molecules

Normally here the components have a union of atoms, start to be useful, and be more visible.

Organisms

It's a combination of atoms and molecules forming bigger sections in the application.

Templates

This part consists of a group of organisms forming a page, but personally I don't use in every project I made.

 

This is a good way to think even if you're not following this sort of structure. Just because you're not using e.g. a button for multiple purposes right now, that doesn't mean you won't as the project comes closer to fruition.

 

Thinking in react is actually a good read if you're still in doubt about when should you create a component: reactjs.org/docs/thinking-in-react....

The question When should you create a component ? can be best answered by answering another question Why should you create a component ?. Reason for creating new components are:

  • You want to reuse the code, and you want to keep your code DRY.
  • You want each component to have a specific and meaningful purpose, to have a Single Responsibility.
  • You want to keep different layers of the app (such as data, presentation and any other middle layers) separately, to follow Separation of Concerns pattern.
 

This is an interesting thought. As someone who is also new to React, making almost everything a component makes sense. At the same time, for a small app or project, it could be overboard.

For the first full react project I did, everything event headers was a component but I had requirements I was trying to meet.

 

See my comment about familiarizing yourself with context. It's a huge help to treat it as second nature to keep shared local state, and will improve the readability of your code by breaking into smaller files even if you don't immediately have a case for code reuse.

@helderburato 's comment about atoms, molecules, organisms and templates is helpful too, even if you don't follow his structure.

 

Consider using eslint-plugin-react-perf, it will guide you sometimes when you need to create new components. I mean rendering presentations for complicated data structures.

 

Another thing to think about when deciding when to split into components: React.lazy/dynamic imports and code-splitting your bundles. Not only do you gain the performance benefit of only loading things when you need them, but you can for example further secure* parts of your app which require authentication by not even loading them for unauthorized users (an "auth gate").

*This is not bulletproof, but rather complimentary. Real security happens on the backend, even if you're using serverless functions, DBaaS, etc. for that.

 

In smaller, less complex apps I like to write everything in App.js, and spread out components to separate files in the last step just before deployment.

 

Your state management is going to be a big factor, but it doesn't have to be complicated. In fact, you can make your life much simpler by developing the right habits. I'm not even referring to global state libraries like Redux.

KISS is important, but a single file with hundreds of lines of code you didn't split up, because you didn't see a clear case for code reuse, is hardly keeping it simple.

Something to consider when you start feeling trepidation about breaking up into components, as I'm sure most of us felt when we got started with React and went through the annoyance of prop drilling (and we all probably at some point avoided splitting components as much as we should have as a result):

Context is your friend. Learn it. Use it often, wrapping with a context provider every level where it makes sense to share local state between components therein, without reaching higher for global state (forms are a perfect example).

You may even find that this eliminates your need for Redux and the like for global state (though don't follow the "everything consuming a top level context" pattern like so many "WE DON'T NEED REDUX ANYMORE!!!" tutorials have taught, as that's going to cause unnecessary rerenders and eventually affect performance). Having them at multiple levels really isn't that hard to track/manage in most cases, especially if you're documenting your code properly. Save top level context for things which are unlikely to change often or at all.

Since context is a part of React itself, basing your state management on it even allows you to be ready for Concurrent Mode right now (and obviously reduces your bundle size).

 

Even I have started learning React recently. And I think App.js should have minimum jsx code and it should reference other components in it.
This will be the best way to create reusable components.

 

Good thinking ahead.