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
/containersBy 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
/ducksI believe this hybrid nicely supports apps that emphasize composition.
Key points:
/componentscontains HoCs (higher-order components) and other simple components. These are your building blocks./ducksis like/components, except with higher-order ducks (reducers/actions). Implements Erik Rasmussen’s “Ducks” proposal.feature/index.jsis the Redux-connected container, composed of building blocks from/components.feature/component.jsis the stateless, presentational component also composed from/components.feature/duck.jsis composed from/ducksand 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.