Skip to content

Instantly share code, notes, and snippets.

@KATT
Created February 24, 2023 12:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KATT/9821281d1eee3a4d3bec74693687409a to your computer and use it in GitHub Desktop.
Save KATT/9821281d1eee3a4d3bec74693687409a to your computer and use it in GitHub Desktop.

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.

Why colocating code is often preferable over breaking it up into files

Optimize for code deletability confidence in changes

  • 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 than pages/X

Context switching

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 exported in a components/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.

"DRY" programming is overrated

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

To answer specific points

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 a CreateNewEventDialog 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!

Possible other solutions

  • 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 with pages/event-types.tsx would need to live in somewhere like components/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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment