The lego concept

It's not just react

This is my personal perspective of how a React (or React-Native) project should be structured. It allow a separation of concerns, an isolation of components and even we have several files it's important to keep in mind that's better to have a couple extra files instead of a gigantic file with more than 300 loc.

the concept

The idea behind this concept is to have a directory for dumb and unitary components, for example, buttons, labels, loading, etc.

A lot of these components are already implemented if you use a library, i.e. native-base however you probably will need to customize, for example, a button, then that custom component must be implemented into components/ directory.

Unless the component requires it, most of the times they will be stateless components.

The next stage is the scene which is the UI visual representation, it's the screen but without any of the redux connection. This idea came from the web where we can use storybook to allow developers, designers and stakeholders to see the UI screens without requiring them to load and to interact with the whole app.

This components will be placed inside containers/ContainerName/scene.js and most of the time it will be an stateless component, a clear exception to this is a form scene which should be an stateful component in order to manage the form state, validate it before to send its data to the respective container.

Which leads us to the container which is the smart component that wires up the UI to the redux state, call any action triggered by the user or by any UI interaction. It's located into containers/ContainerName/index.js

dir structure

  • e2e/ // detox
    • .eslintrc // custom eslint rules for detox specs
    • config.json
    • init.js
    • <SpecToTest>.spec.js
  • config/
    • jest.config.js
    • jest.setup.js
    • jest.setupTests.js
    • reactotron.config.js
  • app/
    • components/
      • ComponentName/
        • tests/
          • <componentName>.test.js
        • index.js
        • styles.js
        • types.js // if flowtype is being used
      • componentsStyles.js // if there're some generic styles for all components
      • utils/ // if there's any util library, functions to be used by all components
    • containers/
      • Root/ // THIS IS THE IMPORTANT ONE, DO NOT REMOVE IT
        • index.js
        • reducers.js // HERE'S WHEE YOU SHOULD IMPORT ALL REDUCERS
        • routes.js // HERE'S WHERE YOU SHOULD IMPORT THE CONTAINERS THAT ARE PART OF THE APP NAVIGATION
        • sagas.js // HERE'S WHERE YOU SHOULD IMPORT THE SAGAS TO BE USED AND FORK THEM
        • store.js // configure store
      • ContainerName/
        • tests/
          • <containerName>.test.js
        • index.js
        • scene.js
        • styles.js
        • types.js // if flowtype is being used
      • containersStyles.js // if there're some generic styles for all containers
      • utils/ // if there's any util library, functions to be used by all containers
    • state/ // redux state Files
      • StateName/ // think of it as the model
        • tests/
          • actions.test.js
          • reducer.test.js
          • saga.test.js
          • selectors.test.js
        • actions.js
        • reducer.js
        • saga.js
        • selectors.js
        • types.js // if flowtype is being used
    • utils/ // any util lib or file to be used accross the app
      • tests/
    • variables/
      • Colors.js
      • UI.js