ProNextJS
    lesson

    Organizing Component Files

    Jack HerringtonJack Herrington

    Organizing your components can be a surprising challenge you'll face. While there's no single "right" way to do it, making smart choices early on will help your project's maintainability. Let's look at some approaches and best practices for structuring your components well.

    One Component Per File

    A common strategy is to stick to "one component per file".

    My personal rule of thumb is one exported component per file, with files ideally less than 100 lines and not bigger than around 250 lines.

    Let's walk through some examples to see how I arrived at this rule. Each of these examples do the same thing, but take different routes to get there.

    Example 1: One Mega Component

    In the first example, 01-one-component-per-file-large, we take the layout from a designer or toolkit and drop it directly into the application code. The result is one mega component that is 850 lines long.

    This approach takes the "one component per file" rule too far. It is unmaintainable and has terrible performance because any state change will cause the entire component to re-render. It needs to be broken up into smaller components.

    Example 2: Nested Components (Don't Do This!)

    In the second example 02-nested-components-do-not-do, we break the component into smaller nested components inside the main component.

    As seen in this screenshot of the code, the MobileLinks component is nested inside the HomePage component:

    Example of nested components

    While this approach breaks the component into smaller parts, nesting like this is something you should never do!

    The React documentation specifically warns against this practice because it kills performance. Every time the main component re-renders, there's a new reference to each nested component, breaking React's caching and forcing it to re-render everything inefficiently.

    Example 3: Single File with Smaller, Non-Exported Components

    In the third example 03-one-exported-component-per-file we have a single file with smaller, non-exported components. The main exported component is at the end of the file, while the other components are not exported by the module.

    This approach provides good privacy, as the components that shouldn't be reused are not exported. However, the downside is that the file ends up being 922 lines, which is longer than the original example case we looked at.

    Example 4: Components in Separate Files

    The fourth and final example 04-one-component-per-file-small takes each component and puts it into its own file. The components are located in a separate directory and are exported individually:

    Components are imported from separate files

    Most of these files are between 50 to 100 lines, with only the Header being around 243 lines, which is still relatively maintainable.

    The downside is that we have many small exported components, and if we're exporting a component, it implies that it should be reusable. However, most of these components shouldn't necessarily be reused.

    On the plus side, since the components directory is still in the main route, it's clear that the components are intended to be used only by this route and its descendant routes.

    Deciding on Component Organization Rules

    When deciding on your team's rules for how many components to have per file and whether to export them or keep them private, it's important to also consider the ideal maximum line count for your components. These two factors are closely related.

    You'll likely encounter this decision early in your application development, especially when building out the app shell, header, footer, and navigation components. How you structure these components in the file system and files will set the standard for the entire app going forward.

    Transcript

    Organizing your components can be a surprising challenge when it comes to any React application, of course, that includes Next.js apps. If you get it right, it can be very easy to find your components, they'll be reasonably sized, and it'll be clear which ones you're reusing and which ones are private. Some folks prefer to stick with a simple rule, one component per file. And whether you want to follow that rule is something you're probably going to hit pretty early on in your application development because you'll get some huge page mocks or HTML from a designer and how to structure that in a components is probably going to be your first challenge in your app. Now my personal rule of thumb is one exported component per file.

    And in general, I prefer to have files less than 100 lines and definitely not bigger than say 250 lines. So let me walk you through some examples so that I can show you how I arrive at that personal one exported component per file rule. So in the repo that's associated with this video, there are four different directories of four different projects. They all do exactly the same thing, but they take different routes to get there. Now, the first one I'm going to look at is 01-1-component-for-file-large.

    This is what you get when you take that layout from your designer or from a toolkit and you just drop it into the code for your application, you get one mega component that is 850 lines long. And to me, that's an example of taking the one component per file rule too far, because you don't factor in the potential size of those components. And this is just unmaintainable. And it also has terrible performance, Because any state change, and there's actually a state at the top of this file, will cause the entire component to re-render. And it's a huge component.

    So we don't want that. We want to break it up into smaller components. Now, getting clever for a second, let me show you what you should never do. And that is to nest components. So we take a look over here at zero two, nested components do not do.

    We'll take a look at the page in there. And again, I have this warning at the top, don't do this. So we look down at the component in this case, we have broken it up into smaller components. Here we got a mobile links component that is a smaller component, but we've nested those components inside of the homepage component. And that's terrible.

    There's literally a specific warning in a React documentation saying, never do this. You know, on its face, it looks like a good idea, but it kills performance. So you should not do this. The reason it kills performance is because every time that homepage re-renders there is a new reference to every single component in here like mobile links and it basically breaks up all of React's caching. So React ends up having to re-render everything every time and it's just very inefficient.

    But of course having broken this up into smaller components is really good. So let's see one option that may be okay and that's number three. We have a single file but it's got lots of smaller components that aren't exported. So now all the way down at the end of this file, We have the one exported homepage component, but everywhere between here and there are components that are not exported by this module. So the privacy is good.

    The things that you should not reuse are not exported. But the downside is that you've got now a 922 line file, so it's actually even a little bit worse than what we had in the 01 original case. So our fourth and final example takes each one of these components out and puts it into its own file. So you can see in the app you've got page, you've also got this directory full of components and each one of these components is broken out into its own file and exported. And in general most of these files are in the 50 to 100 lines with only one of these being outstanding, which is the header, which I think around 243 lines, which is still pretty maintainable, I'd say.

    Now the downside here is that we have all of these small exported components, and if we're exporting a component and saying we should reuse this, then Most of these components really shouldn't be reused. On the plus side, because this is still in the main route, the components directory is still in that main route, it's pretty clear the components are only to be used at least by this route and maybe any routes that descend from it. So at the end here, when you decide with your team about your rules for how many components you want per file, and if that means exported or just flatly single components in there and not any private components or whatever, please, I would say also at the same time, decide on the ideal maximum line count for your components. Since those two, as you can see, are pretty related. And as I say, I think you're going to run into this pretty quickly when it comes to your application development because the first thing you're probably going to get is the app shell and building out the header and the footer and all the nav stuff is a pretty big component.

    So how you're going to structure that in the file system and in the files is going to set the standard for how you structure the entire app going forward.