Skip to content
This repository has been archived by the owner on Jul 3, 2020. It is now read-only.

Latest commit

 

History

History
184 lines (130 loc) · 5.66 KB

02-best-pratices.md

File metadata and controls

184 lines (130 loc) · 5.66 KB

Best Practices

Here you can read about how we build our React applications.

React

React is a widely-used library from Facebook for building user interfaces.

Components

Use stateless functional components when possible. Class components are only necessary when you need a local state, e.g. input fields.

Logic should not be performed in the render method or in functional components, because it may have severe performance implications. The reason for this is that components may be rendered tens of times every second, which in turn means that the logic will be evaluated as many times.

Do

const Hello = ({message}) =>
  <h1>Hello World</h1>

Do NOT do

class Hello extends Component {
  render() {
    return <h1>Hello World</h1>
  }
}

Higher-Order Components

Use higher-order components (or decorators) to reuse component logic. A higher-order component is a function that takes a component and returns a new component.

Context

Use context together with [higher-order components](#Higher-Order Components) to pass props down the component tree when necessary. Context should be avoided when possible, because it makes the application more complex and harder to understand.

State

Use MobX to manage the application state in separate stores.

You should also let MobX manage component state.

Do

import React, {Component} from 'react'
import {observable} from 'mobx'
import {observer} from 'mobx-react'

class Hello extends Component {
  @observable message: string = ''

  render() {
    return (
      <div>
        <p>{this.message}</p>
        <button onClick={() => this.message = 'Hello.'}>Say Hello</button>
      </div>
    )
  }
}

Do NOT do

import React, {Component} from 'react'

type State = {
  message: string,
}

class Hello extends Component {
  state: State = {message: ''}

  render() {
    return (
      <div>
        <p>{this.state.message}</p>
        <button onClick={() => this.setState({message: 'Hello.'}}>Say Hello</button>
      </div>
    )
  }
}

Example

You can use this very project as a real-world example of how to combine all of this for your projects.

Resources

Routing

Use React Router to create routes for your application.

Utilities

Use lodash (or a similar utility library) instead of writing your own utility functions. Even though you might think that you do not need an utility library at first, you will need it sooner or later.

Here are some useful utility functions:

Structure

Try keep your direction structure as flat as possible and group your code by feature, and not by type. Nothing is more frustrating than navigating the file tree every time you need to find the selector for the component you are working on or the reducer that you are writing a test for. It is much easier to place all files that are associated with each other under the same directory.

React components are an exception to this, because it is better to keep them separate for clarity.

Note: Your source code should always be placed in a src directory.

Do

src/
  todo/
    components/
      Todos.js
      Todo.css
    actions.js
    reducer.js
    selectors.js
    spec.js
  index.js
  test.js

Do NOT do

src/
  actions/
    todo.js
  components/
    Todos.js
  reducers/
    todo.js
  selectors/
    todo.js
  styles
    Todo.css
spec/
  todo.js

Testing

You should write unit tests at least for the most important parts of your application, because it will make it easier to both develop and refactor the application. Having some unit tests will also make it easier for new developers to join project, as they can verify that everything still works as intended after making a change.

Focus on writing unit tests that ensure that your application is behaves correctly instead of testing every part of the application separately. Testing everything separately is time-consuming and it makes refactoring the application a nightmare, because you will spend a lot of time updating the test cases.

We have found Jest and Enzyme to be the best libraries for testing React applications.

Protip: You can use Jest Snapshot Testing to test your React components without writing complex test cases.

Quality Assurance

Use Husky to ensure that the code works before it is committed.

You should run at least the following tasks before each commit:

  • Linting
  • Unit tests
  • Type-checking (if applicable)

Protip: Husky supports all Git hooks. Simply add the corresponding npm script to your package.json.