Skip to content

Instantly share code, notes, and snippets.

@agarrharr
Last active October 11, 2017 17:00
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 agarrharr/3e3bfc74c2e980c291b7ab01b8370ba9 to your computer and use it in GitHub Desktop.
Save agarrharr/3e3bfc74c2e980c291b7ab01b8370ba9 to your computer and use it in GitHub Desktop.
React/Redux Code Style

React/Redux Code Style

Redux

General

  • Store the minimum amount of data necessary to describe the entire state of the app
  • Use selectors to derive information from the store

Directory Structure

  • Directory that matches your state tree structure.
    • The top level state should be singular and camelCase (contact not contacts, contactGroup not contactGroups)

    • Each branch of the tree is its own directory.

    • Don't nest state directories because it doesn't add a lot of value. Keep it flat.

    • Just have one reducer, one actions, and one selector file for each part of the state

      components
        Button.js
        Icon.js
        MessageInput.js
      state
        actionTypes.js
        store.js
        contact
          index.js (reducer)
          contactActions.js (action creators)
          contactSelectors.js
        contactGroup
          index.js
          contactGroupActions.js
          contactGroupSelectors.js
      

Action Types

  • Use actions types to describe actions that the user starts and any resulting success or failure from the server.

  • Action types should not describe every part of the state, but general actions that the user can take.

    For example, you don't need all of these action types when the user clicks save to update their profile:

    CONTACT__NAME_UPDATED
    CONTACT__ADDRESS_UPDATED
    CONTACT__PHONE_NUMBER_UPDATED
    

    because you could just have one action type that describes all possible changes to their profile.

    CONTACT__UPDATED
    
  • Action types file should export an object where the keys and values are the action types

    export default createConstantObject(
      'CONTACT__LOAD_REQUESTED',
      'CONTACT__LOAD_SUCEEDED',
      'CONTACT__LOAD_FAILED',
    );
  • Import actions types as TYPES

    import TYPES from '../actionTypes'
  • Action type names

    • All uppercase
    • Last part should be a verb in the past tense
    TOP_STATE__THING_HAPPENED
       |             |
       |             |- Describes the action in past tense (`CONTACTS_ADDED`, `CONTACTS_REMOVED`, `STARRED`, `MARK_UNREAD_FAILED`)
       |
       |- The name of the top level state (`CONTACT`, `CONTACT_GROUP`)
    
  • Async actions

    • Use 3 action TYPES that end in REQUESTED, SUCCEEDED, FAILED

Action Creators

  • Async actions should use redux thunk.

  • The consumer should not be able to tell the difference between calling an synchronous or asynchronous action creator.

  • Async actions should optimistically update the state and roll it back if the request fails.

  • Async actions can also set an isLoading flag on request and set it back to false on success or fail.

Services

  • Use services for api calls and side effects and localstorage (use promises)
fetchMessages().then(() => {}, () => {}) // not .catch()

Selectors

  • Use selector functions instead of accessing the store directly

  • Export the presentational component for testing and Storybook

  • Export the container component as default

  • You can memoize your selectors

React

  • Boolean props

    • Should start with is or has
  • Callback props

    • Callback prop names should start with on (onClick, onToggle).
    • Functions passed to callback props should start with handle (<Button onClick={this.handleBackClick}>Back</Button>).
  • Render props

    • Render props are usually better than higher order components.
    • Make sure you have propTypes on children (children: PropTypes.func.isRequired).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment