Even though users don’t care about your file structure and a correct one doesn’t exist, I’ve a habit of experimenting with them in my React/Redux applications.
The two most popular I’ve tried are by nature and by domain.
By nature
/src
/components
/reducers
/actions
/containers
By domain
/src
/feature1
component.js
reducer.js
actions.js
container.js
/feature2
component.js
reducer.js
actions.js
container.js
“By nature” is perfect for smaller apps and beginners learning React/Redux. Everything is self-explanatory and sits with its own kind.
“By domain” makes larger apps easier to think about as everything’s broken up by what it does, not what it is.
I love them both, but feel something’s missing. Neither lend themselves well to the mantra, “composition over inheritance”. I don’t feel like my features are compositions of many components, reducers, and actions.
So what if we fused these two popular paradigms?
A Composable, Hybrid Structure
/src
/features
/feature1
index.js
component.js
duck.js
/components
/ducks
I believe this hybrid nicely supports apps that emphasize composition.
Key points:
/components
contains HoCs (higher-order components) and other simple components. These are your building blocks./ducks
is like/components
, except with higher-order ducks (reducers/actions). Implements Erik Rasmussen’s “Ducks” proposal.feature/index.js
is the Redux-connected container, composed of building blocks from/components
.feature/component.js
is the stateless, presentational component also composed from/components
.feature/duck.js
is composed from/ducks
and is used in your Redux store.
I purposely excluded the router, store, root reducer and unit tests because that’s all subjective.
The main point is to think about your features as composing a bunch of components, reducers, and actions, which are all just functions.