React コンポーネントを書くとき、基本的に
- イベントハンドラ系のメソッドは
on~
で始める -
render
が長くなってきたらメソッドに切り出し、render~
という名前にする - ライフサイクル系のメソッドは先に書く
- render 系のメソッドは最後にまとめて書く(一番最後が
render
)
といったような自分ルールを設けてます。
せっかくなのでこれも ESLint でチェックできないかと思って調べてみたら
eslint-plugin-react にちゃんとそういうルールがありました。
デフォルトのルール
デフォルトのルールでは以下のような順番だそう。
- static メソッドやプロパティ
- ライフサイクルメソッド
- 独自で定義したメソッド
render
このうち、2 のライフサイクルメソッドとは、具体的には以下のメソッド。順番もこの順。
- displayName
- propTypes
- contextTypes
- childContextTypes
- mixins
- statics
- defaultProps
- constructor
- getDefaultProps
- getInitialState
- state
- getChildContext
- componentWillMount
- componentDidMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- componentDidUpdate
- componentWillUnmount
カスタマイズする
このルールを自分好みにカスタマイズするには、.eslintrc
にルールを記述します。
{
"extends": "airbnb",
"rules": {
"react/sort-comp": [2, {
order: [
'type-annotations',
'static-methods',
'lifecycle',
'/^on.+$/',
'everything-else',
'rendering',
],
groups: {
rendering: [
'/^render.+$/',
'render',
],
},
}],
}
}
react/sort-comp
の第二引数にオブジェクトを記述します。
オブジェクトの order
に、チェックしたいルールを好きな順番で記述していきます。
order
に指定できるのは static-methods
や lifecycle
など最初から使えるグループに加え、
"/^on.+$/"
のように正規表現で指定したり、
'rendering',
],
groups: {
rendering: [
'/^render.+$/',
'render',
],
},
のように、groups
部分に独自のグループを定義して、そのグループ名を order
内で使うといったこともできます。
というわけで上記の例では
-
type-annotations
: Flow 用。type Props
が先頭に必要?(まだ Flow 試せてない) -
static-methods
: static メソッド -
lifecycle
: ライフサイクルメソッド -
/^on.+$/
:on~
で始まるイベントハンドラ -
everything-else
: その他 -
rendering
:render~
メソッド群と、最後にrender
という順番でないと lint エラーになるよう設定できました。
eslint-config-airbnb でも指定されてた
後でわかったんですが、eslint-config-airbnb 使っていれば定義済みですね。
https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb/rules/react.js#L204-L216
// Enforce component methods order
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md
'react/sort-comp': ['error', {
order: [
'static-methods',
'lifecycle',
'/^on.+$/',
'/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
'everything-else',
'/^render.+$/',
'render'
],
}],
だいたい一緒だし、わざわざ自分で定義する必要なかったなあ。