react-nativeにESLint(airbnb style)を適用した際のビフォーアフター

react-nativeプロジェクト作成直後のコードにairbnbスタイルを適用してみます。

# 新規プロジェクト作成

```
react-native init AwesomeProject
```

なお環境はMacOSX El Capitan、react-nativeのバージョンは0.32.0です。
この状態の`index.ios.js`は以下のようになります。

```javascript
import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View
} from 'react-native';

class AwesomeProject extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
```

# ESLint airbnbスタイル導入
https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb
を参考に。

```sh
(
  export PKG=eslint-config-airbnb;
  npm info "$PKG" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs npm install --save-dev "$PKG"
)
```

`.eslintrc`をプロジェクトルートに作成し、`airbnb`を`extends`します。

```json
{
  "extends": "airbnb"
}
```

お好みのエディタでLinter機能をONにします。
画像はAtomの[linter-eslint](https://atom.io/packages/linter-eslint)プラグインを利用したものです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/6287/3bdee161-5455-2f74-3f1b-7ae01ac82d1b.png" width="640">

# エラーの解消
[jsx-filename-extensionルール](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md)に関してだけは`.js`も許可したいので、以下のように`.eslintrc`を修正します。

```json
{
  "extends": "airbnb",
  "rules": {
    "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
  }
}
```

全てのエラーを全て解消すると以下のようになりました。

```javascript
import React from 'react'; // ④
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,  // ①
} from 'react-native';

// ②
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// ③
const AwesomeProject = () => (
  <View style={styles.container}>
    <Text style={styles.welcome}>
      Welcome to React Native!
    </Text>
    <Text style={styles.instructions}>
      To get started, edit index.ios.js
    </Text>
    <Text style={styles.instructions}>
      Press Cmd+R to reload,{'\n'}
      Cmd+D or shake for dev menu
    </Text>
  </View>
);

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
```

# 変更点
## [①comma-double](http://eslint.org/docs/rules/comma-dangle)
最後のカンマも省略せずに追加しています。

##[②no-use-before-define](http://eslint.org/docs/rules/no-use-before-define)
変数は利用する位置よりも前に移動します。

##[③react/prefer-stateless-function](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
stateやconstructorやreactのライフサイクルメソッドを利用していない場合は、Stateless Functionsで記述します。

##[④no-unused-vars](http://eslint.org/docs/rules/no-unused-vars)
③の適用で不要になった{ Component }を削除します。

# まとめ
Stateless Functionsを適用すると [Presentational Component と Container Component](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) がはっきりするので良いかもしれません。（airbnbスタイルに限った話ではないですが）