I've been working with React since 2015 so it's more than "a feeling", so trying to put words on my reasoning below. Obviously open for input and to be proven wrong.
- Once you remove
pages/X.jsx
and everything is vendored - you'll automatically delete all the dependencies without leaving any traces - With our linting, you will prompted to delete unused code automatically
- Certainty that you can delete or update code - deleting something in
components/X
is a lot scarier thanpages/X
When one wants to find what component is responsible for a specific thing in the UI - you usually start in the known entry point - in Next.js that is pages/X.jsx
and navigate to the export default
- then find the component you're looking for there
Once you then navigate (simple CMD+click) into the component you want to change you'll be faced with two different scenarios:
- A) The component is in the same file and not exported - you can safely know that the component is not re-used and you can modify it without further thinking
- B) The component is
export
ed in acomponents/X
directory- I now need to at the minumum need to check all places that import this file which breaks my flow of what I'm doing
- If the component is reused I have to consider all of those cases before I change it - changes that also need to be tested.
Trying to "over-share" code leads to very complicated logic where it's a lot easier to copy and tweak than to make reusable parts for everything. "WET" programming is easy for anyone to pick up and it'll make it a lot cheaper to delete code.
See scenario B) on Context Switching above
You don't use cmd + P that often I guess. I expect components to live in their respective files for easy finding and navigation. That's the point of React componentization IMO. Files should be kept lean and modular.
No, I don't - I mainly navigate by reading and clicking.
As I pointed out, this has been brought up by React core team members. Below are quoted by Dan Abramov on Twitter:
Good feedback. Also I think we reached the point where abstraction is necessary
https://kentcdodds.com/blog/when-to-break-up-a-component-into-multiple-components
- 100% for something like a
<Dialog/>
that needs to look and feel consistent but not for something like aCreateNewEventDialog
which is used once. It's the wrong abstraction - we need to look at the smaller parts - i.e. making a<FormDialog/>
first - This blog post is focused on breaking up into multiple components - not multiple files
- He also quotes this: Duplication is far cheaper than the wrong abstraction. — Sandi Metz
- And his ending point is: So feel free to break up your components into smaller ones, but don't be afraid of a growing component until you start experiencing real problems. It's WAY easier to maintain it until it needs to be broken up than maintain a pre-mature abstraction. Good luck!
- There might be a way to keep components in the
pages/X
-folders without Next.js treating it as a Page - then context switching and the surrounding uncertainty would be reduced - Namespaces / Modules
- Strict folder naming in
components/
to show that code is tied to a specific page. I.e. anything to do withpages/event-types.tsx
would need to live in somewhere likecomponents/pages/event-types/MyComponent.tsx
- Maybe there could be a linter to help us delete "stray" files in
components/
- but since we're not really using TypeScript it will be hard to do this with certainty.