Skip to content

Instantly share code, notes, and snippets.

@chris-pearce
Last active June 15, 2019 23:04
Show Gist options
  • Save chris-pearce/edb7fe04487e4e4a4d5baa6f0ecbde46 to your computer and use it in GitHub Desktop.
Save chris-pearce/edb7fe04487e4e4a4d5baa6f0ecbde46 to your computer and use it in GitHub Desktop.

App Conventions

React and JavaScript

  • Components should be written as function components only. In case they need access to local state and/or side-effects (life cycle methods) Hooks should be used. That is, no ES6 classes anymore.

  • Follow the Container and Presentational design pattern.

  • Only use index.js files for exporting modules and don't use them within every folder instead reserve them for root folders such as src/components.

  • All component props should have type definitions using the prop-types library.

  • For components, use an arrow function.

  • Destructure props consistently, i.e., pick a way and stick to it.

  • Use the shorthand version of React.Fragment, e.g.: <>Contents</>.

  • Use early return in functions. It is easier to read, avoids unnecessary indentation especially when there are several conditions in a row and emphasises the "core" of the function.

    Don't do this:

    function notUsingEarlyReturn(arg1, arg2) {
      if (arg1) {
        const foo = someOtherFunction(arg2);
        if (foo) {
          const baz = anotherFunction(foo);
          return baz;
        } else {
          return 'No foo...';
        }
        } else {
          return 'No arg1...';
        }
    }

    Do this:

    function usingEarlyReturn(arg1, arg2) {
      if (!arg1) {
        return 'No arg1...';
      }
    
      const foo = someOtherFunction(arg2);
      if (!foo) {
        return 'No foo...';
      }
    
      const baz = anotherFunction(foo);
      return baz;
    }
  • Avoid multi-level spreading of component props, e.g.:

    <MembershipApp
      {...{
        ...props,
        heading: 'Heading',
        content: 'Content',
      }}
    />

    It makes it less obvious as to what props that component expects. Instead, explicitly declare each individual prop and only spread the remaining props:

    <MembershipApp
      heading="Heading"
      content="Content"
      {...props}
    />
  • For component API's prefer enums over booleans.

CSS

  • Avoid inline styles.

More to come…

Presentational Components

Testing

  • Avoid testing implementation details instead focus more on end user concerns.
  • For unit tests:
    • Use React Testing Library instead of Enzyme.

    • Test things that actually need testing, e.g., any state changes. Tests such as "should render correctly" are a waste of time.

    • Avoid toMatchSnapshot() tests instead use something like snapshot-diff. An example:

      it(`snapshots the difference between 'associatedTextIds' being applied`, () => {
        expect(
          snapshotDiff(
            <Fieldset {...requiredProps}>{children}</Fieldset>,
            <Fieldset {...requiredProps} associatedTextIds="id1">
              {children}
            </Fieldset>
          )
        ).toMatchSnapshot();
      });
  • For e2e tests avoid brittle selectors such as class, id, element, or any type of attribute selector as these are all implemention details that will change often. Instead, prefer more end user focused selectors such as selecting the text of elements, e.g.:
    this.submitButton = Selector('button').withText(`Continue`);
  • Mock all third-party libraries.

General Code Quality

  • Every piece of code needs to be reviewed by at least one team member. No code is to be merged to master until this happens unless it's a production hot fix 🔥.
  • All JavaScript is linted using ESLint.
  • All CSS is linted using stylelint.
  • Only include code in an app that is actually being used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment