はじめに
筆者はモバイル開発にはFlutter、Web開発にはReactを利用している。両者の違いを考える際に特に気になるのが、Reactがクラスコンポーネントから関数コンポーネントへ移行した理由である。本記事では、その背景に迫りながら、Flutterのクラスコンポーネント(Widget)との比較を通じて、それぞれの特徴やメリット・デメリットを整理する。
なぜReactはクラスではなく関数コンポーネントを選んだのか?
クラスコンポーネントから関数コンポーネントへの移行
Reactではもともと、状態やライフサイクル管理のためにクラスコンポーネントが主流だった。しかし、React 16.8で導入されたHooksの登場により、状態や副作用を簡単に扱えるようになったことで、関数コンポーネントが主流となった。その理由は以下の点に集約される。
- シンプルで直感的なコード: 関数コンポーネントは余分な記述が少なく、コードの可読性とメンテナンス性が向上する。
- 再利用性の向上: カスタムHooksによってロジックを簡単に再利用でき、コードの重複を防げる。
- クラス特有の難しさの排除: 「this」キーワードの混乱や複雑なライフサイクルメソッドを覚える必要がなくなった。
Webフロントエンドでオブジェクト指向は使えないのか?
Webフロントエンドでもオブジェクト指向プログラミング(OOP)は使える。実際、JavaScriptやTypeScriptはオブジェクト指向の特徴を十分に備えている。ただし、Webフロントエンド開発では、DOM操作やUIの状態管理などが頻繁に行われ、関数型プログラミングの特性(状態管理の明確化や副作用の制御)がコードのシンプルさや保守性向上に大きく寄与することから、Reactのように関数コンポーネントが主流となった経緯がある。
React Hooksを用いた状態管理の実例
import React, { useState, useEffect } from 'react';
const Timer: React.FC = () => {
const [time, setTime] = useState(0);
useEffect(() => {
const timerId = setInterval(() => setTime((t) => t + 1), 1000);
return () => clearInterval(timerId);
}, []);
return <div>経過時間: {time}</div>;
};
export default Timer;
一方、Flutterがクラスコンポーネントを維持する理由
Flutterでは、UIを構築するためにOOPをベースにしたクラスコンポーネントを採用している。これはDartの言語特性とFlutterのアーキテクチャに深く結びついている。
- オブジェクト指向の活用: ウィジェットの再利用性と拡張性が高く、状態をクラス内部で明示的に管理できる。
- ライフサイクルメソッドの明確化: 状態管理やリソース解放などが直感的に管理できる。
- 型安全性と明示的な設計: Dartの特性を活かして、厳密で明確なコードが記述できる。
Flutterクラスコンポーネントの実例
import 'package:flutter/material.dart';
class CounterWidget extends StatefulWidget {
final int initialValue;
const CounterWidget({Key? key, this.initialValue = 0}) : super(key: key);
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
late int _count;
@override
void initState() {
super.initState();
_count = widget.initialValue;
}
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(onPressed: _increment, child: Text('+1')),
],
);
}
}
React HooksとFlutter Providerの比較
React Hooks
- メリット: シンプルで直感的、再利用性が高い。
- デメリット: 慣れないと複雑な状態管理で混乱する場合がある。
Flutter Provider
- メリット: 明示的でクラスベースのため、構造化が容易。
- デメリット: 状態が肥大化すると管理が煩雑になることがある。
どちらを選ぶべきか?
React + HooksがWebフロントエンドに適している理由
- DOM操作やレンダリング最適化が容易であり、パフォーマンス調整が柔軟に行える。
- 関数型アプローチによりコードの軽量化やメンテナンス性が向上し、SPAやSSRなど多様なWebアプリケーション開発に適している。
Flutter + クラスコンポーネントがクロスプラットフォーム開発に適している理由
- Dartのコンパイル性能とOOPによる構造的明確さが、異なるプラットフォーム間での互換性を保ちやすくする。
- ウィジェットベースの明示的な設計により、複数環境間でのUIの一貫性や保守性が担保される。
まとめ
Reactが関数コンポーネントを採用した理由は、シンプルさと再利用性、コードの直感的な理解を向上させることにある。一方、Flutterがクラスベースの設計を維持しているのは、OOPの明示的かつ構造化された設計思想に基づいているからである。プロジェクトの性質や開発チームのスキルセットを考慮して適切な技術を選択することで、開発効率や保守性が大きく向上する。