⚖️

FlutterとReactNativeを比較してみた...

2024/03/20に公開

実際のところどうなのか?

こんにちわJboyです〜
今日は普段はFlutterで開発をしている私が、ReactNativeを学習する機会があったので、個人的な感想ですが、比較をしてみようと思います。SwiftUIやJetpack Composeとも比較したいですが、Nativeで作った方が安定して、クロスプラットフォーム独特のエラーや面倒臭い環境構築でハマることがないので、モバイルアプリを作りたいなら、プロジェクト作ってビルドするだけのSwiftかKotlinをおすすめします。

Flutter知らない人のためにご紹介すると、Googleが開発したiOS、Android、Web、Desktopアプリが開発できるクロスプラットフォームと呼ばれている技術です。日本では流行っているのか、新規開発で使われているようですね。
有名どころだと、TOYOTA、リクルート、GMOペパボ、mixiですね。

https://docs.flutter.dev/

ReactNative知らない人のためにご紹介すると、Meta社(旧FaceBook社)が開発したReact.jsでモバイルアプリを開発できるようにしたクロスプラットフォームでFlutterが登場する前からあって昔から使われています。他には、XmarinとかIonicとかCordovaってのがありますね。

採用してる企業あるのか...
あった笑
DMM、DENA、楽天ですかね。メルカリも使ってたような...
海外だと、Microsoft、Discord、pumaかな?

https://reactnative.dev/

Flutterと同じようにモバイル、Web、Desktopが作れるみたいですね。
本当に作れんだ....
https://necolas.github.io/react-native-web/
https://microsoft.github.io/react-native-windows/

実際のところどうなのか?

Flutterのメリット

  1. 公式ドキュメントが充実している.
  2. パッケージの開発が盛んにおこなわれている.
  3. コードを書けばUIが作れるWidgetで快適に開発ができる.
  4. AltJSのDartはオブジェクト思考の技術なので、C#やJavaに慣れていれば学習しやすい.

ReactNative Expoのメリット

  1. JavaScriptかTypeScriptが書けて、Reactの知識があれば理解しやすい.
  2. Reactで使うuseStateなど共通したコードがある.
  3. Webのエンジニアなら学習コストを下げれそうだと思った。しかしFlutterでもキャッチアップはしやすい.
  4. npmのエコシステムが使える。そのままJavaScriptのライブラリが使えたりする.

Flutterのデメリット

  1. Nativeの機能を使うときに、Swift, Kotlin, x-code, build.gradleなどの知識が必要になる.
  2. Flutterしか知らないと、Nativeのコードをいじるときにおまじないでコピペして終わることが多い.
  3. 調べればエラーは大抵解決できるけど、Nativeに依存したパッケージがサポートされなくなったら、違うパッケージを探す必要がある.
  4. GraphQLと相性が悪そう???、ReactNativeよりコードがわかりずらい.

ReactNative Expoのデメリット

  1. styleSheetなるもはCSSと似てるけど別物。独特のレイアウトを覚えないといけない.
  2. UIを作るなら、Flutterの方が圧倒的に早い!、レイアウトを整えるは時間かかりそう.
  3. コードを書けばUIを作れる宣言的UIであるSwiftUIとJetpack Composeの方が、UI作るのは簡単そう。Nativeの方が最近は使いやすいかもしれない.
  4. JavaScript系のコードを書くので、Swirt, Kotlinの知識を活かせる場面がない.

カウンターアプリを作ってみる

比較対象にならないと思いますが、どれぐらいの量のコードを書くのか?、カウンターを作るのにどれぐらいの知識がいるのか試してみました。ReactNativeの方は、ボタンのデザインはText Buttonなので、簡略化されてます😅

Flutterで作る
Flutterの場合だと、main関数を書いて、runApp書いて、MaterialAppがあるMyAppを書いて、カウンターのUIを作るMyHomePageクラスが必要です。
コードの保管機能もあるから、クラスで書いても難しくはない。コードの量が多いけど、部品ごとに分かれているので、ルールを覚えればUI作るのは簡単です。

// Copyright 2019 the Dart project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    super.key,
    required this.title,
  });

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

ReactNative Expoで作る
CSSのFlexBoxのようなスタイルを適用して、画面中央にコンポーネントを配置。コード量思ったよりは多くはない。ReactHooksを使ったことがあれば似てるので、理解しやすいですね。カウンターのロジックは、useStateで状態の管理をします。FlutterのsetStateの原型になったものですかね。
counter の中に、初期値の0が入ってます。Buttonをタップすると、setCounterの中で、counterに1を足していって、画面が更新されて数字がカウントされていきます。

import React, { useState } from 'react';
import { Button, Text, View, StyleSheet } from 'react-native';

const App = () => {
  const [counter, setCounter] = useState(0);

  return (
    <View style={styles.container}>
      <Text style={styles.text}>You have pushed the button this many times:</Text>
      <Text style={styles.counter}>{counter}</Text>
      <Button title="Increment" onPress={() => setCounter(counter + 1)} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 24,
  },
  counter: {
    fontSize: 48,
    margin: 20,
  },
});

export default App;

まとめ

FlutterとReactNativeを比較してみましたが、Flutterは元々はiOSとAndroidの技術を使っていたモバイルエンジニアが使う技術らしく、ReactNativeはJavaScriptを書いていたWebのエンジニアが同じWebの技術でモバイルアプリを開発するために作られたそうです。

でもまあ、WebのエンジニアでもReactやってた人はFlutterはライフサイクルが似てるから早くキャッチアップできるから、ReactNativeを選ぶ必要があるのだろうかって疑問がありますね。React好きだけど、ReactNative嫌いな人いますからね。

僕が、ReactNativeを勉強してみようと思った理由は最近接触してきたある企業の人が、Flutterを新規開発で使うかもしれないらしいがどうなのかと聞いてきて、GraphQLを使うみたいで、相性悪そ〜って思って比較をしてみたのですが、Flutterには、ferryとか専用のパッケージがありましたが、ReactのGraphQLよりコードが読みづらいのと、情報が少ないので、試しにやってみたReactNativeで、GraphQLを使った方が、Reactの書き方をそのまま使えそうで、個人の考えですけど、GraphQLと相性が良さそうだと思いました。

なので、REST APIやFirebaseで開発しないようなので、開発実績があったReactNative + GraphQLをおすすめしましたね。

仮に仕事引き受けたら、苦しむの私なので😅

記事書いたので読み比べてみてください〜い。今回はReactNativeをおすすめする笑
ferryってライブラリは難しくてわからなかった。スッゲー使いずらいです💦

https://zenn.dev/flutteruniv_dev/articles/7efdc2a8126564
https://zenn.dev/joo_hashi/articles/3aa9e53fb8c78c

Discussion