React NativeのComponent Libraryはどれ使えばいいか

# はじめに
React Nativeを「いざやってみよう」と思うと、Component Libraryが複数存在し、どれがいいのかわからなくなります。というか、自分はわかりません。
なので、今回は、実際ライブラリを使ってみて、それぞれの使い心地などの試してみました。
コンポーネントを、すべて試せるほどの時間があるわけではないので、どんなアプリを実装するにも必ず必要であろうButton Componentを今回は実装してみて、その作り込み度合いで、ライブラリがどんな感じかを見ていきたいと思います。

## 今回比較するライブラリとバージョン

```
"react-native-elements": "^3.4.2"
"native-base": "^3.1.0"
"react-native-ui-lib": "^6.0.0"
"@ui-kitten/components": "^5.1.1"
"react-native-paper": "^4.9.2"
```

# 結論
時間無い人向けに、ひとまず結論から

* 一番おすすめ → [React Native Elements](https://reactnativeelements.com/)
* デザインを細かく設定したい → [Native Base](https://nativebase.io/)
* デザイン済みのコンポーネントを使いたい → [React Native UI Kitten](https://akveo.github.io/react-native-ui-kitten/)
* Material Designを使いたい → [React Native Paper](https://callstack.github.io/react-native-paper/index.html)

次から、内容です。

# [React Native Elements](https://reactnativeelements.com/)

## 見た目
![Screenshot_20210920-143519930_jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277608/87614422-b604-abd8-fc7e-96e3f2eb78be.png)

## コード
``` typescript
export const ReactNativeElementButtons: React.VFC = () => {

    return (
        <View style={styles.container}>
            <Card containerStyle={styles.card}>
                <Card.Title><Text h3>React Native Elements</Text></Card.Title>
                <Button title="ボタン"  containerStyle={styles.button} />
                <Button title="背景なし" type='clear' containerStyle={styles.button} />
                <Button title="影付き" raised containerStyle={styles.button} />
                <Button title="アウトライン" type='outline'  containerStyle={styles.button} />
                <Button title="無効" disabled containerStyle={styles.button} />
                <Button title="読み込み中" loading={true}  containerStyle={styles.button} />
                <Button icon={<Icon type='font-awesome-5' name="thumbs-up" size={15} color="white"/>} title="アイコン付き" containerStyle={styles.button}/>
            </Card>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { width: '100%',  alignItems: 'center', justifyContent: 'center',},
    card: { width: '90%', marginBottom: 10},
    button: {marginBottom: 5}
});

```
## 所感
* Css in JSでスタイルを書く。
* loadingやdisabled、outlineなど、ほしいApiは一通りきちんと揃っている。
* ダークモードもきちんと備えている。
* スタイルを設定するときも違和感なく設定できる。個人的にすごく使いやすい。
* starが多いだけの安定感。導入してから、ボタンを配置して、エラー出ず利用できた。
* ドキュメントもコンポーネントのスクショがあるので、見やすい
* iconもたくさん揃っている。
* デフォルトのデザインは普通すぎる感じはする。
* 色の設定がしやすいわけではない。secondaryカラーにするためのAPIがなかったりする。

# [Native Base](https://nativebase.io/)
## 見た目
![Screenshot_20210920-143519930_jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277608/8af5e923-7bf4-dd30-9460-a643962ac171.png)

## コード
```typescript

export const NativeBaseButtons: React.VFC = () => {

    return (
        <View style={styles.container}>
            <NativeBaseProvider>
                <Center>
                    <Box border={1} borderRadius='xl' borderColor='#f1f1f1' shadow={1} width='90%' height='100%' padding={4} >
                        <Heading marginBottom={3}>Native Base</Heading>
                        <Button size='md' marginBottom={2}>ボタン</Button>
                        <Button size='md' marginBottom={2} colorScheme="secondary" >セカンダリー</Button>
                        <Button size='md' marginBottom={2} backgroundColor="emerald.400">カスタムカラー</Button>
                        <Button size='md' marginBottom={2} variant='outline'>アウトライン</Button>
                        <Button size='md' marginBottom={2} variant='ghost'>ゴースト</Button>
                        <Button size='md' marginBottom={2} isDisabled>無効</Button>
                        <Button size='md' marginBottom={2} isLoading>読み込み中</Button>
                        <Button startIcon={<Icon as={MaterialCommunityIcons} name="email" size={5} />} variant="outline">
                            Email
                        </Button>
                    </Box>
                </Center>
            </NativeBaseProvider>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { width: '100%', height: 500, marginBottom:10},
});

```
## 所感
* Utility Firstでスタイルをかける。
* isLoadingやisDisabled、variant='outline' colorScheme="secondary" など、ほしいApiは一通りきちんと揃っている。
* ダークモードもある。
* UIがデフォルトがきれい。
* カスタマイズがしやすい。Design tokensという仕組みがあり、primaryカラーの中でも細かく設定したりできる。
* <Center>や<Flex>などのコンテナーレベルのコンポーネントがある。個人的にはそれが手になじまない感じがする。
* iconもたくさん揃っている。
* documentが個人的には好きではない。コンポーネントのデザインを見たいとき、expo.devなので開いてから見るまで時間がかかる。


# [React Native UI Lib](https://wix.github.io/react-native-ui-lib/)

## 見た目
![Screenshot_20210920-143519930_jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277608/ad984397-3d41-2112-817f-5a04808b4c6d.png)

## コード
```typescript
export const ReactNativeUiLibButtons: React.VFC = () => {

    return (
        <View flex width='100%' center marginT-10>
            <Card flex activeOpacity={1} width='90%' height={250} centerH marginB-10>
                <Text text30 grey10 marginB-10>ReactNativeUiLib</Text>
                <Button text70 white background-orange30 label="ボタン" marginB-10/>
                <Button text70 background-orange30 label="outline" outline marginB-10/>
                <Button text70 white background-orange30 disabled label='無効なボタン' marginB-10/>
                <Button text70 outline label="Share" marginB-10 iconSource={settingsIcon}/>
            </Card>
        </View>
    )
}
```
## 所感
* Utility Firstでスタイルをかける。書き方がすごくTailwindっぽい。
* デザインがデフォルトでもきれい。
* ダークモードも一応ある。
* outlineとdisabledがあるが、loadingは自分で実装する必要がある
* webでビルドすると落ちるので、iOSとAndroidでしか使えない ("^6.0.0")
* iconがついていないので、画像で設定する必要がある


# [React Native UI Kitten](https://akveo.github.io/react-native-ui-kitten/)

## 見た目
![Screenshot_20210920-143519930_jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277608/88ada381-81bb-5fef-db11-c4c4cdc4d9fa.png)

## コード
```typescript
export const ReactNativeUiKittensButtons: React.VFC = () => {

    return (
        <View style={styles.container} >
            <IconRegistry icons={EvaIconsPack} />
            <ApplicationProvider {...eva} theme={eva.light} >
               <View style={styles.cardContainer}>
                   <Card style={styles.card}>
                       <Text category='h3' style={styles.title}>React Native UI Kitten</Text>
                       <Button style={styles.button}>ボタン</Button>
                       <Button style={styles.button} appearance='outline' >アウトライン</Button>
                       <Button style={styles.button} >アウトライン</Button>
                       <Button style={styles.button} disabled >無効</Button>
                       <Button style={styles.button} appearance='outline' accessoryLeft={<View><Spinner size='small'/></View>}>読み込み</Button>
                       <Button style={styles.button} appearance='outline' accessoryLeft={<Icon name='sun-outline'/>}>アイコンボタン</Button>
                   </Card>
               </View>
            </ApplicationProvider>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { width: '100%', height: 370, marginBottom:10 },
    cardContainer: { width: '100%', alignItems: 'center', justifyContent: 'center'},
    card: { alignItems: 'center', justifyContent: 'center', width: '90%'},
    title: {marginBottom:10},
    button: { marginBottom: 5},
    indicator: { justifyContent: 'center', alignItems: 'center' },
});

```
## 所感
* CSS in JSでスタイルを書く。
* デザインのデフォルトでもきれい。
* すでにデザインシステムがあり、ある程度はデザインしなくても済む(Eva Design System)
* ダークモードもある。ダークモードへの切り替えが楽。
* ドキュメントが見やすい。
* outlineとdisabledがあるが、loadingは自分で実装する必要がある。
* アイコンセットもある。ただ、アイコンが少ない感じはある
* スタイルの設定が少し癖がある気がする。ちょっと触ったときにスタイルが思ったとおりに行かなかった。


# [React Native Paper](https://callstack.github.io/react-native-paper/index.html)

## 見た目
![Screenshot_20210920-143519930_jpg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277608/13eb5859-9b22-1d08-a068-e5656e5b02f1.png)

## コード
```typescript
export const ReactNativePaperButtons: React.VFC = () => {

    return (
        <View style={styles.container}>
            <PaperProvider>
                <View style={styles.cardContainer}>
                    <Card style={styles.card}>
                        <Card.Title title="React Native Paper"/>
                        <Card.Content>
                            <Button style={styles.button}>ボタン</Button>
                            <Button style={styles.button} mode="contained">ボタン</Button>
                            <Button style={styles.button} mode="outlined">ボタン</Button>
                            <Button style={styles.button} disabled >無効</Button>
                            <Button style={styles.button} icon="camera" mode="outlined">カメラ</Button>
                            <Button style={styles.button} loading mode="outlined">読み込み中</Button>
                        </Card.Content>
                    </Card>
                </View>
            </PaperProvider>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { width: '100%', height: 420, marginBottom:10},
    cardContainer: { width: '100%', alignItems: 'center', justifyContent: 'center'},
    button: {marginBottom: 5},
    card: {width: '90%'}
});

```
## 所感
* CSS in JSでスタイルを書く
* 意識せずともMaterial Designになる。
* ボタンのアイコンの使いやすさが異常
* ダークモードもある。
* ドキュメントが見やすい。
* outline disabled loading などほしいAPIはすでにある。
* アイコンセットも豊富にある。
* 違和感なくスタイルできることができた。


# まとめ

* React Native Element
    * スタイル適応やAPIやドキュメントは文句なく、安定感のある動作を見たので、コレを使っとけば問題は起きないだろうなと思いました。導入時にエラーが発生することもなかったので、使い終わった後のストレスが一番少なかったです。個人的には、デザインも可もなく不可もなくなので、一番無難な感じです。
* React Base
    * デザインがもとよりきれいな上、細く設定ができるので、デザインを細かくカスタマイズしたい人向けだと思いました。
* React Native UI Lib
    * すごくTailwindっぽく書けて、書き方は個人的には好みですが、アイコンセットがないのは、微妙でした。ただ、UIはきれいなので、乞うご期待ではあります。
* React Native UI Kitten
    * デザイン済みなうえ、ドキュメントも見やすかったので、デザインで手間かけたくないって人におすすめです。[Demo App](https://akveo.github.io/react-native-ui-kitten/#kitten-tricks)にもたくさんのデザインされた画面があるので、そのへんも参考にしながら作ると、デザイン周りは考える量が減って楽かと思います。
* React Native Paper
    * 個人的にはMaterial Designは好きではないので、このライブラリに惹かれませんが、Material Designを書きたい人はコレだろうとも思います。ボタンのアイコン表示は簡単にでき、基本的なAPIも使いやすいので、Material Designしたい人はコレです。(2回目)