Skip to content

JavaScript: React

Zander Martineau edited this page May 15, 2017 · 1 revision

Creating a React app

When we start a new React app, the first question we need to answer is whether or not it will include our Kickoff front-end framework.

If the answer is no, we will use Create React App

If the answer is yes, we will use Create Kickoff App

Both of these projects automate the proper set up of new apps, including using Webpack for module bundling and hot-reloading for development servers.

The latter also includes the Kickoff framework, allowing you to customise a copy of the Kickoff source to suit your project.

Other React-family libraries

Libraries like React Router, Redux, or RxJS may be added as and when appropriate. They should not however, be included "out of the box" as each project will differ.

As with adding any packages, it is important to avoid complexity for complexity's sake.

Ask yourself what the capabilities you want the application to have are, and whether or not that should rely on a library for managing complex state (Redux). It may be enough to have Higher-Order-Components which hold State for their children.

Writing React

Functional Components

Wherever possible, we should be writing functional components. Compare the following examples:-

import React from 'react'

const Greeting = ({ name }) => <div>Hello {name}!</div>

export default Greeting
import React, { Component } from 'react'

class Greeting extends Component {
  constructor (props) {
    super(props)
  }

  render () {
    return (
      <div>Hello {this.props.name}!</div>
    )
  }
}

export default Greeting

This is because not only is it more efficient for us to write as few lines as possible, but internally React is able to treat functional components as not having any backing State which can speed up DOM reconciliation when calculating updates.

Naturally there will be sensible cases where a component needs a local state (e.g. a Dropdown which can be expanded or unexpanded, with options that are fetched dynamically from a server).

In these cases extending Component may be warranted, but in an ideal world we would either inherit from PureComponent or implement a reliable shouldComponentUpdate() lifecycle method on the class instance.

Examples

  • use ES6 import syntax
  • only import the things you need rather than requiring the entire module and then only using part
// Good
import React, { Component } from 'react'

// Bad
var React = require('react')
var Component = React.Component

  • separate your const declarations and your exports
  • often we need to wrap exports in styling or data handling libraries (e.g. Radium, GraphQL, etc.)
// Good
const Greeting = () => {
  ...
}

export default Greeting

// Bad
export default Greeting = () => {
  ...
}

  • use Object destructuring to only expose required props to component functions
  • don't keep referencing this.props or this.state
  • don't declare new variables from this.props or this.state
// Good
const Greeting = ({ name }) => <div>Hello {name}!</div>

// Bad
const Greeting = () => <div>Hello {this.props.name}!</div>

// Also Bad
const Greeting = () => {
  var name = this.props.name
  return <div>Hello {name}!</div>
}

  • use ES6 Arrow function syntax
// Good
const Greeting = () => <div>...</div>

// Bad
function Greeting () {
  return <div>...</div>
}

Fetching Data

If a component needs to load some data before rendering, this data should be fetching in a componentWillMount() method. It should not be fetching in either the constructor() or render() methods.

This could be either a direct AJAX call or an Action dispatch if using a state management library such as Redux.

The reason for this is so that data fetching does not block rendering. You should include a loading... message or component while you are waiting for the response of your AJAX call.

Utility functions

Where it makes sense, abstract utility functions out to a separate module that can be imported by components which depend on that function.

As a general rule, keep components as thin, light, and testable as possible. Avoid using Mixins - these are now considered harmful.

Clone this wiki locally