Skip to content

Code styleguide

Tim Stirrat edited this page May 12, 2020 · 9 revisions

General

No magic numbers or strings

Use constants for special numbers.

- arr.slice(0, 14);
+ arr.slice(0, MAX_EXPOSURE_DAYS);

Note: Array index 0 is not special, and well understood.

Use switch statements

When a piece of logic can branch in more than 3 directions, use a switch statement.

switch(val) {
  case 1:
    break;
  case 2:
    break;
  case 3:
    break;
  default:
    break;
}

Modules

Use named exports

Named exports have slightly better developer ergonomics in IDEs. The IDE can read the named export in files across the project even if you have not imported it before.

Default exports are not easily discovered and lead to inconsistent names.

export const MY_CONST = 1234;
export class MyClass {}

Imports will always use consistent names. Names can be overridden with as, if needed.

import {MyClass} from './MyClass';
import {MY_CONST as CONST} from './MyClass';

React components (general)

Use functional components

export const MyComponent = () => {
  return <View />;
}

Use object spread assignment

This will clearly express inputs and outputs.

export const MyComponent = ({navigation, label}) => {
  return <View onPress={() => navigation.foo()}>{label}</View>;
}

JSDoc comment your input props

This will help the IDE infer types

/**
 * @param {{
 *   navigation: Navigation;
 *   label: string;
 * }} param0
 */
export const MyComponent = ({navigation, label}) => {
  return ...;
}

Use components, not methods, to group smaller abstractions of functionality

  <View>
-   {getSpecialViewStuff(label, color)}
+   <SpecialViewStuff label={label} color={color} />
  </View>

Use hooks

Hooks will keep your components concise.

export const MyComponent = () => {
  const [message, setMessage] = useState('hello');

  return <Text>{message}</Text>;
}

Keep complicated state or "business logic" out of views

Write custom hooks, with tests, to keep components small and reactive

export const MyComponent = () => {
  // example, not a real hook
  const [state, enable, disable] = useLocationTrackingState()

  return (
    <Text onPress={() => disable()}>
      {state === ENABLED ? 'Enabled': 'Disabled'}
    </Text>
  );
}

Common components

Theme

Wrap your views with <Theme> to ensure correctly colored text, backgrounds (and eventually buttons and inputs). <Theme> tags can be nested, they will change all children's colors.

Read the docs

<Theme use="default" setBackground>
  <Typography>Violet on light violet background</Theme>
  <Typography secondary>Light violet</Theme>
  <Theme use="charcoal" setBackground>{/* charcoal background with white text */}</Theme>
</Theme>

Typography

Use <Typography> where possible. It assigns text color, size and line heigth.

Read the docs

<Typography monospace>Regular color, monospace, regular size (18px/24px)</Theme>
<Typography secondary use="body3">Muted color, smaller text (15px/24px)</Theme>

{/* styles for spacing are allowed */}
<Typography style={{paddingVertical: 8}}>Extra spacing</Theme>

Theme aware components

If you need to use theme colors such as border colors, or need a theme aware component, use emotion.sh styled components:

import styled from `@emotion/native`;

const themeBorder = ({theme}) => theme.border;
const themeTextPrimary = ({theme}) => theme.textPrimaryOnBackground;

const MyComponent = styled.View`
  border-color: ${themeBorder};
  color: ${themeTextPrimary};
`;

Styled components, not required

Note: Feel free to use regular StyleSheet.create() for every day styling, but when your component needs to use theme properties, it will need to use Styled components.

Emotion Styled components are a nice way to create clear semantic names for components. Instead of reading many Views, one can make clearer descriptions of the UI:

import styled from `@emotion/native`;

function Comp() {
  return (
    <InlineRow>
      <Link onPress={...}>Left</Link>
      <Flex />
      <Link onPress={...}>Right</Link>
    </InlineRow>
  );
}

const InlineRow = styled.View`
  flex-direction: row;
  align-content: center;
`;

const Flex = styled.View`
  flex: 1;
`;

const Link = styled.TouchableOpacity`
  color: blue;
  text-decoration-line: underline;
`;
Clone this wiki locally