Code that works together, stays together
When I was first starting as a junior programmer I would always get lost when looking at backend code.
I assumed that part of it was because I was a junior developer; that I did javascript instead of whatever language was used in that backend; and that frontend development was very different from backend.
I worked with backends in php and python, with several frameworks, and every time I would feel lost during the first couple of weeks. No matter how many times I would encounter the MVC (Model-View-Controller) pattern, I would always feel lost and would have a hard time figuring out in what files was the code I needed to change.
As I worked more and more on such projects, and gained experienced in software architecture, I realized that the problem was not so much the complexity of the code or the patterns, but how the code was organized and structured into different folders and files.
If you did frontend before react and the advent of Component frameworks, you probably faced the same issue. HTML files were in a templates folder, css in a styles and js in script. These folders would then have several levels of subfolders divided by pattern, others by functionality and others would just be random, like utils, assets or whatever name seemed convenient at the time. Things were separated by format, or pattern, or some other random logic that made some kind of sense. The senior engineers in the project always felt the architecture made perfect sense due to habit and would not easily empathize with the hardships of new developers.
Now... Have you ever heard about Hebb's rule? Hebb's rule comes from neuroscience and can be simplified as:
“Neurons that fire together wire together”
One of the main take aways of this rule, is brain plasticity. Brain plasticity is the fact that when different neurons work together to achieve something, they all create stronger connections and group into networks.
Code should be similar. Code that works together to achieve something, starts to be tightly coupled and should be grouped together.
If you have a template, css, js and some assets that render a certain route, they should all be in the same folder that represents that route. If they form a reusable component, they should all be in the folder for that component. This also applies to the backend. If you have an API, with a specific view, that uses a form, and a specific serializer, instead of having a the view in a folder with all the views, the form in one with all the forms and the serializer in one with all the serializers, those files should be together.
Once you understand this, you will understand why JSX, who contradicted all the conventions at the time, is now so widely adopted and paved the way for Component frameworks. Before JSX it was common place to have code split based on file format, and not on functionality. Adding a feature meant adding 3 new files and changing a few more, across different folders and subfolders. JSX allowed for logic, template and style to all co-exist in the same place; making it easier to create or change code when working on a specific functionality.
This also applies to hooks. Before hooks your logic in your component would be spread around different life-cycle methods. Now you can put together the logic that works together, in the form of a custom hook.
Before I go, let me just say that this doesn't mean that you should have a monolith with all your code. No, this means that you should group and split your code based on functionality.
To sum it up:
Code that works together, stays together