Skip to main content

react/useSortComp

This rule enforces methods and properties order. When creating React components it is more convenient to always follow the same organisation for method order to help you easily find lifecycle methods, event handlers, etc.

ESLint Equivalent: sort-comp

Examples

Invalid

// Must force a lifecycle method to be placed before render
class Hello extends React.Component {
	render() {
		return <div>Hello</div>;
	}
	displayName = 'Hello'
};

 file.tsx:3:1 lint/react/useSortComp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  render should be placed after displayName.

    1// Must force a lifecycle method to be placed before render
    2class Hello extends React.Component {
  > 3  render() {
       ^^^^^^
    4    return <div>Hello</div>;
    5  }

  When creating React components it is more convenient to always follow
    the same organisation for method order to help you easily find
    lifecycle methods, event handlers, etc.


// Must force a custom method to be placed before render
class Hello extends React.Component {
	render() {
		return <div>Hello</div>;
	}
	onClick() {}
};

 file.tsx:3:1 lint/react/useSortComp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  render should be placed after onClick.

    1// Must force a custom method to be placed before render
    2class Hello extends React.Component {
  > 3  render() {
       ^^^^^^
    4    return <div>Hello</div>;
    5  }

  When creating React components it is more convenient to always follow
    the same organisation for method order to help you easily find
    lifecycle methods, event handlers, etc.


// Must force a custom method to be placed before render, even in function
var Hello = () => {
	return class Test extends React.Component {
		render () {
			return <div>Hello</div>;
		}
		onClick () {}
	}
};

 file.tsx:4:2 lint/react/useSortComp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  render should be placed after onClick.

    2var Hello = () => {
    3  return class Test extends React.Component {
  > 4    render () {
         ^^^^^^
    5      return <div>Hello</div>;
    6    }

  When creating React components it is more convenient to always follow
    the same organisation for method order to help you easily find
    lifecycle methods, event handlers, etc.


// Type Annotations should not be at the top by default
class Hello extends React.Component {
	props: { text: string };
	constructor() {}
	state: Object = {};
	render() {
		return <div>{this.props.text}</div>;
	}
}

 file.tsx:3:1 lint/react/useSortComp ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  props should be placed after render.

    1// Type Annotations should not be at the top by default
    2class Hello extends React.Component {
  > 3  props: { text: string };
       ^^^^^
    4  constructor() {}
    5  state: Object = {};

  When creating React components it is more convenient to always follow
    the same organisation for method order to help you easily find
    lifecycle methods, event handlers, etc.

Valid

// Must validate a full class
class Hello extends React.Component {
  displayName = ''
  propTypes = {}
  contextTypes = {}
  childContextTypes = {}
  mixins = []
  statics = {}
  getDefaultProps() {}
  getInitialState() {}
  getChildContext() {}
  componentWillMount() {}
  componentDidMount() {}
  componentWillReceiveProps() {}
  shouldComponentUpdate() {}
  componentWillUpdate() {}
  componentDidUpdate() {}
  componentWillUnmount() {}
  render() {
    return <div>Hello</div>;
  }
};
// Must validate a class with missing groups
class Hello extends React.Component {
  render() {
    return <div>Hello</div>;
  }
};
// Must put a custom method in 'everything-else'
class Hello extends React.Component {
  onClick() {}
  render() {
    return <button onClick={this.onClick}>Hello</button>;
  }
};
// Must validate a full React class
class Hello extends React.Component {
  displayName = ''
  propTypes = {}
  contextTypes = {}
  childContextTypes = {}
  mixins = []
  statics = {}
  getDefaultProps() {}
  getInitialState() {}
  getChildContext() {}
  UNSAFE_componentWillMount() {}
  componentDidMount() {}
  UNSAFE_componentWillReceiveProps() {}
  shouldComponentUpdate() {}
  UNSAFE_componentWillUpdate() {}
  getSnapshotBeforeUpdate() {}
  componentDidUpdate() {}
  componentDidCatch() {}
  componentWillUnmount() {}
  render() {
    return <div>Hello</div>;
  }
};
// Must validate React 16.3 lifecycle methods with the default parser
class Hello extends React.Component {
	constructor() {}
	static getDerivedStateFromProps() {}
	UNSAFE_componentWillMount() {}
	componentDidMount() {}
	UNSAFE_componentWillReceiveProps() {}
	shouldComponentUpdate() {}
	UNSAFE_componentWillUpdate() {}
	getSnapshotBeforeUpdate() {}
	componentDidUpdate() {}
	componentDidCatch() {}
	componentWillUnmount() {}
	testInstanceMethod() {}
	render() { return (<div>Hello</div>); }
}
// Must validate a full React 16.3 ES6 class
class Hello extends React.Component {
	static displayName = ''
	static propTypes = {}
	static defaultProps = {}
	constructor() {}
	state = {}
	static getDerivedStateFromProps = () => {}
	UNSAFE_componentWillMount = () => {}
	componentDidMount = () => {}
	UNSAFE_componentWillReceiveProps = () => {}
	shouldComponentUpdate = () => {}
	UNSAFE_componentWillUpdate = () => {}
	getSnapshotBeforeUpdate = () => {}
	componentDidUpdate = () => {}
	componentDidCatch = () => {}
	componentWillUnmount = () => {}
	testArrowMethod = () => {}
	testInstanceMethod() {}
	render = () => (<div>Hello</div>)
}
// Must allow us to use 'constructor' as a method name
class Hello extends React.Component {
	constructor() {}
	displayName() {}
	render() {
		return <div>Hello</div>;
	}
}
// Must ignore stateless components
function Hello(props) {
	return <div>Hello {props.name}</div>
}
// Must ignore stateless components (arrow function with explicit return)
var Hello = props => (
	<div>Hello {props.name}</div>
)
// Non-react classes should be ignored, even in expressions
class Hello {
	render() {
		return <div>{this.props.text}</div>;
	}
	props: { text: string };
	constructor() {}
	state: Object = {};
}
// Non-react classes should be ignored, even in expressions
const foo = class {
	render() {
		return <div>{this.props.text}</div>;
	}
	props: { text: string };
	constructor() {}
	state: Object = {};
}
// static lifecycle methods can be grouped (with lifecycle)
class Hello extends React.Component {
	constructor() {}
	static getDerivedStateFromProps() {}
}
class MyComponent extends React.Component {
  static propTypes;
  state = {};
  foo;
  render() {
    return null;
  }
}
class MyComponent extends React.Component {
  static getDerivedStateFromProps() {}
  static foo;
  render() {
    return null;
  }
}
class MyComponent extends React.Component {
  static getDerivedStateFromProps() {}
  static foo = 'some-str';
  render() {
    return null;
  }
}
class MyComponent extends React.Component {
  static getDerivedStateFromProps() {}
  foo = {};
  static bar = 0;
  render() {
    return null;
  }
}
class MyComponent extends React.Component {
  static getDerivedStateFromProps() {}
  static bar = 1;
  foo = {};
  render() {
    return null;
  }
}
class MyComponent extends React.Component {
  constructor() {
    super(props);
    this.state = {};
  }
  static foo = 1;
  bar;
  render() {
    return null;
  }
}