-
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.jsfiles for exporting modules and don't use them within every folder instead reserve them for root folders such assrc/components. -
All component props should have type definitions using the
prop-typeslibrary. -
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.
- Avoid inline styles.
More to come…
- Are domain agnostic (a good tool for this is Storybook).
- Are unit tested excluding implementation details.
- Are browser tested.
- Are accessible, e.g.:
- Semantic and valid HTML has been used.
- All visual elements have a text representation.
- Is accessible with a keyboard.
- If necassary, WAI-ARIA has been used.
- Avoid using the
nodeprop type if children are known ahead of time.
- Avoid bloated third-party frameworks such as Bootstrap and Foundation instead make use of specialised libraries that do one thing and one thing well, e.g., downshift, react-modal, etc.
- 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 likesnapshot-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.