react/sort-comp

Enforce the order of methods and properties in a class component

When every class component lists its members in the same order, you know where to look. Lifecycle methods are at the top and render is at the bottom.

The default order is static methods, then lifecycle methods, then everything else, then render. The lifecycle methods are ordered too, roughly in the order React calls them: constructor, then componentDidMount, then componentDidUpdate, then componentWillUnmount.

The rule checks classes and createReactClass() objects. It ignores function components.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"react/sort-comp" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"react/sort-comp" = ["error", {
  order = ["static-methods", "lifecycle", "everything-else", "render"],
  groups = {},
}]

Examples#

Reported:

class Profile extends React.Component {
  render() {
    return <button onClick={this.handleClick}>{this.props.name}</button>;
  }

  handleClick() {
    this.props.onSelect();
  }

  componentDidMount() {
    this.props.load();
  }
}

Not reported:

class Profile extends React.Component {
  componentDidMount() {
    this.props.load();
  }

  handleClick() {
    this.props.onSelect();
  }

  render() {
    return <button onClick={this.handleClick}>{this.props.name}</button>;
  }
}

Options#

OptionDefaultWhat it does
order["static-methods", "lifecycle", "everything-else", "render"]The order. Each entry is a member name, a pattern such as "/^handle.+$/", or the name of a group.
groups{}Your own groups. Each key is a group name, and each value is a list of member names and patterns. Defining lifecycle replaces the built-in list.

These groups are built in:

GroupWhat is in it
lifecycledisplayName, propTypes, contextTypes, childContextTypes, mixins, statics, defaultProps, constructor, getDefaultProps, state, getInitialState, getChildContext, getDerivedStateFromProps, componentWillMount, componentDidMount, componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, getSnapshotBeforeUpdate, componentDidUpdate, componentDidCatch, componentWillUnmount, in this order. Each UNSAFE_ name comes right after the name without the prefix.
static-variables, static-methodsStatic fields, and static methods.
instance-variables, instance-methodsClass fields that don't hold a function, and class fields that do.
getters, settersget and set accessors.
type-annotationsFields that have a type and no value.
everything-elseAnything no other entry matches.

This config puts the event handlers right before the methods that render:

bunfig.toml
[lint.rules]
"react/sort-comp" = ["error", {
  order = ["lifecycle", "everything-else", "handlers", "rendering"],
  groups = {
    handlers = ["/^handle.+$/"],
    rendering = ["/^render.+$/", "render"],
  },
}]

With it, this is reported, because handleClick comes before fullName:

class Profile extends React.Component {
  handleClick() {
    this.props.onSelect();
  }

  fullName() {
    return this.props.first + " " + this.props.last;
  }

  render() {
    return <button onClick={this.handleClick}>{this.fullName()}</button>;
  }
}

And this isn't:

class Profile extends React.Component {
  fullName() {
    return this.props.first + " " + this.props.last;
  }

  handleClick() {
    this.props.onSelect();
  }

  renderName() {
    return <span>{this.fullName()}</span>;
  }

  render() {
    return <button onClick={this.handleClick}>{this.renderName()}</button>;
  }
}