Hopp til hovedinnhold

Structuring your React app is incredibly important for making your project maintainable and easy to navigate. What is the best way to do it?

Whenever I start out a new app, I tend to ask myself the question, "How should I structure my files?" Truth is, this is a hard question to answer. There is no single right way to make sure the next developer understands where each file should be, and there are tons of alternatives. However, I have a way that has worked for me, and there are several other ones that work just as well. This article is going to outline a few of them.

My way

I tend to split my app into two main topics - components and containers. Containers are basically one-off layout views for a particular route, while components tend to be (mostly) reusable pieces of code. In addition, I separate out state logic (like Redux's dispatchers, actions and reducers) and reusable logical containers. The last piece in the puzzle is utilities. Whenever I bootstrap a new application, I use mkdir -p to create the following application structure:

src
  actions
  components
  containers
  dispatchers
  reducers
  utils

Components

I tend to create a folder for each component. I add an index.js file in each of these to simplify importing each component. Inside this folder, I add potential styles, tests, and the component itself. If a component is a bit large and needs to be split into several distinct (but not reusable) components, each of these are also placed in here. Here's an example of how I'd structure a component:

some-component
  index.js
  SomeComponent.css
  SomeComponent.js
  SomeComponent.spec.js
  SomeComponentSubPart.js
  README.md

Depending on the component, and the application itself, I consider adding a README.md file, as well, explaining the usage and use cases for that particular component. Naming can often only get you so far - sometimes the use case (and limitations) needs some explaining. The same rules go for containers, really.

Redux folders

Actions, dispatchers and reducers always get their own folders in my projects, each with their own index.js file. For actions and dispatchers, the index.js file works as an export aggregator, so that I can import * as actions from '../actions'; instead of remembering which file my particular action (or dispatcher) is from. This practice also pushes me to create unique action (or dispatcher) names for each one - simplifying understanding the code later on. The reducers folder follows the same structure, only with a slightly more complex index.js file. This time, I export the result of redux's combineReducers function - so that I can create my store with a simple import.

The highway

My way isn't necessarily the only one that'll work for you. Perhaps your projects require a different approach altogether. That's totally fine! Luckily, there are several other approaches that lets you get away with significantly less folders, files and navigation. For simple applications, a "no structure" approach is totally fine. This web app is structured like that, for instance (go check out the source code!). Simply put all your components in the same root folder, and whenever the application reaches a certain size (this one never did), you can consider adding more structure as you go.

Where to put the tests?

There are people that love co-locating tests with the components / logic they test, and there are people that will never see a piece of test code outside a dedicated test/ folder. Both approaches are fine, and come with their own benefits. To be honest, it's mostly up to taste - so I'm not going to push you either way.

Did you like the post?

Feel free to share it with friends and colleagues