Skip to content

Instantly share code, notes, and snippets.

@nperez0111
Last active June 10, 2019 21:34
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 nperez0111/ceace290e8f1a04912caeebcb91ccddf to your computer and use it in GitHub Desktop.
Save nperez0111/ceace290e8f1a04912caeebcb91ccddf to your computer and use it in GitHub Desktop.
React Redux structure

Methodology

What are some of the most common tasks when building and maintaining a project?

Initial buildout

  • Adding features
    • Creating components, containers, and redux related data (if need be)
  • Modifying existing features
    • Finding components, containers and adding or removing things until the desired outcome is fulfilled

Maintenance of a project

  • Modifying existing features
  • Adding features
  • Updating
    • This is pretty much only done to make it so that adding and modifying large amounts of things at once can be done faster and more efficiently than to work in the outdated codebase

What are we optimizing for?

Well, we should not really consider the initial buildout of a project as our main optimization metric as it only ever happens once in a project's lifecycle. Definitely, maintenance should be optimized for.

What is typical of a developer who is performing maintenance of a project

  • They are unfamiliar with the code base
    • Even if they wrote the codebase we will assume that they only know some general architecture as they have lost context working in other projects

When modifying/adding to a project?

  • They want to locate where to add the feature and add it

Maxim's I want to follow:

  • Finding things should be easy:
    • Things that often change together should be close together (colocation)
    • It should be obvious from the import statement what type a file is
  • Adding things should be easy:
    • Avoid too much nesting (Files should be easy to move around the project and relative importable (the webpack resolvers was a remedy to a problem that shouldn't exist)

File Structure

With file structure there are a few ways to go about it:

  • By Type of file
    • Currently, we are using the type of file wherein we have our reducers, actions, components, containers all separated from each other. When adding a feature it is pretty hard to know where to start first (The component, wait but I don't have the data, what does the data looks like, do I need to fetch it and so on).
  • By Feature
    • I think a better way to do it would be to separate components by a feature like we did inside of the components folder of web-automation but with other related features close by like: containers and presentational component ( if needed: reducers, actions).

In a perfect world, what would an import statement look like

A component named List:

import List from './components/List';

If a component needs a container it should be default export because if a component needs a container it is extremely rare that you would use the component without the container. Instead, it should just be a named export like:

import List from './components/List'; // The container component
import { ListComponent } from './components/List'; // The presentational component

A sub-component named ListItem:

import ListItem from './components/List/Item';

A page named View:

import View from './views/View';
// or maybe
import View from './pages/View';
// or maybe
import View from './routes/View';

// vs. current
import View from './app/View';

A reducer specific to List:

import ListReducer from './components/List/reducer';
// or
import { ListReducer } from './components/List';

// vs. current
import ListReducer from './reducers/List';

An action creator specific to List:

import ListActions from './components/List/actions';
// or
import { ListActions } from './components/List';

// vs. current
import ListActions from './actions/List';

What would a folder structure look like for the above examples?

  • components/
    • ReduxedComponent/
      • SubComponent/
        • actions.js
          • Action creators specific to SubComponent
        • SubComponent.jsx
          • The presentational component for SubComponent
        • index.js
          • The aggregation and export of all files relevant to SubComponent
            • exports { SubComponentActions };
          • The default export would be the presentational component (SubComponent.jsx) in this case because this component does not depend on the redux state
            • export default SubComponent;
      • actions.js
        • Action creators specific to ReduxedComponent and pulls from SubComponent's actions as well
      • ReduxedComponent.jsx
        • This is the presentational component for the ReduxedComponent component
      • ReduxedComponent.js
        • This is the container component for the ReduxedComponent component
      • reducer.js
        • This is the reducer for the ReduxedComponent and all of its descendants
      • index.js
        • The aggregation and export of all files relevant to ReduxedComponent
          • exports { ReduxedComponent, ReduxedComponentActions, ReduxedComponentReducer }
          • Notice that ReduxedComponent exported here is the presentational component
        • The default export is the ReduxedComponent container (ReduxedComponent.js)
          • export default ReduxedComponent;

Pros

In general, if you are looking for anything to do with ReduxedComponent it's very clear what file you should be looking in based upon the file name and path. Except for looking at ReduxedComponent.js from ReduxedComponent.jsx the intuition should be that a .js the file name should be a container while .jsx should be presentational.

Keeps all related files grouped together in the same directory.

Allows for flexibility, more files can be added into this folder like: constants.js, actionTypes.js, utils/ subscribers/ basically anything that is related to the top level component should be placed inside of it.

Cons

Can create a deeply nested hierarchy if we do too many sub-groupings which makes digging for a file difficult

Leads to many files of the same names that are different only in the placement of the directory e.x. actions.js in ReduxedComponent/ and in OtherReduxedComponent/

Possible Variations

Adding .component to the component file

  • ReduxedComponent/
    • ReduxedComponent.component.js
      • Is the container component for ReduxedComponent
    • ReduxedComponent.jsx
      • Is the presentational component for ReduxedComponent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment