airbnb
React
ESLint
reactnative

React Native アプリに eslint-config-airbnb を導入しようとしてハマったポイント

とりあえずインストール

eslint-config-airbnbに必要なパッケージを調べる

Bash
$ yarn info eslint-config-airbnb peerDependencies
{ eslint: '^4.9.0',
  'eslint-plugin-import': '^2.7.0',
  'eslint-plugin-jsx-a11y': '^6.0.2',
  'eslint-plugin-react': '^7.4.0' }

言われるがままインストール

Bash
$ yarn add -D eslint eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-config-airbnb

なぜかbabel-eslintがないと言って怒られた

Bash
$ yarn add -D babel-eslint

ここからスタート

.eslintrc
{
  "extends": "airbnb"
}

1. Unable to resolve module src/App from ~

"react/jsx-filename-extension"をReact Nativeで守ってはダメらしい
素直に.jsに戻し、エラーを抑制

.eslintrc
{
  "extends": "airbnb",
  "rules": {
    "react/jsx-filename-extension": 0
  }
}

2. Unexpected usage of singlequote. (jsx-quotes)

App.js
// NG
<Icon name='menu' style={{ color: 'blue' }} />
// OK
<Icon name="menu" style={{ color: 'blue' }} />

JSXタグ内ではHTMLと同様にダブルクォーテーションを使いましょう。
(※ style={} 内は許される)

3. Component should be written as a pure function (react/prefer-stateless-function)

コンポーネントに React ライフサイクルを利用する部分や state を持たないときは、純粋関数で定義しましょうということらしい。
あの… あとで componentWillMount() を仕込んだり、state を足したりするつもりなんですけど...
いさぎよく以下を追記

.eslintrc
{
  "extends": "airbnb",
  "rules": {
    "react/jsx-filename-extension": 0,
    "react/prefer-stateless-function": [0, { "ignorePureComponents": "true" }
    ]
  }
}

4. Prop type hoge is forbidden (react/forbid-prop-types)

SubComponent.js
SubComponent.propTypes = {
  scores: PropTypes.array.isRequired,  // NG
  datas: PropTypes.object.isRequired,  // NG
};

たんにarrayobjectではその内容がわからん、と。

SubComponent.js
// OK
SubComponent.propTypes = {
  scores: PropTypes.arrayOf(PropTypes.number).isRequired,
  datas: PropTypes.shape({
    created_at: PropTypes.instanceOf(Date),
    chat_string: PropTypes.string,
  }).isRequired,
};

5. Do not use Array index in keys (react/no-array-index-key)

危険だそうです。

App.js
// NG
const ScoreList = props => (
  props.scores.map((score, index) => <ScoreListItem key={index} score={score} />)
);

参考:

App.js
// OK
const ScoreList = props => (
  props.scores.map(score => <ScoreListItem key={score.created_at} score={score} />)
);

ただ、どうしても unique な key がないときもある。
(上記参考サイトより)

  1. the list and items are static–they are not computed and do not change;
  2. the items in the list have no ids;
  3. the list is never reordered or filtered.

最後の手段の一行コメント

App.js
/* eslint react/no-array-index-key: 0  */

const Oracle = props => (
  <Body>
    {props.oracle.map((str, ix) => <Text key={ix} style={styles.text}>{str}</Text>)}
  </Body>
);

/* eslint react/no-array-index-key: 1  */
// もとに戻しておかないとファイル全体でチェックが無効になってしまう

参考にさせていただきました