6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React NativeAdvent Calendar 2020

Day 12

これから ReactNative を使うときに抑えておいた方がいいこと

Last updated at Posted at 2020-12-12

この記事は「React Native Advent Calendar 2020」の12日目の記事です。(忙しくて当日夜になってしまいました、すいません)

自己紹介

バックエンドのエンジニアとしてそろそろ8年になります。
元々、C#, Java, PHPなどでサーバーアプリケーションの構築に関わっていましたが、

最近になり、アプリ開発を行う機会も何度かありました。その中で ReactNative 開発案件に
2度ぶつかり、その中で「これが分かってたら、もうちょっとうまく開発できていたんじゃないか?」
と思うことがあり、これから ReactNative でアプリ開発を行う人向けに情報記載していきます。

なぜ ReactNative にエンカウントするのか...

ReactNative に関わる場合というのは、自分は大きく下記のパターンかと思っています。

  • JavaScript(Vue.js等)でフロント開発をやっていた
  • Reactでフロント開発をやってた
  • Android/iOSでアプリ作っていた

自分は、「Android/iOSでアプリ作っていた」でした。
なお、自分の周りでは大半が「JavaScript(Vue.js/jQuery等)でフロント開発をやっていた」でした。

しかし、ReactNative で安定して開発するためには下記の知識が必要だと思っています。

  • React 知識
  • コンポーネント設計
  • React native パッケージ
  • iOS/Androidアプリ構築に関する知識

それぞれ、どんなことを抑えていればいいかという所感を記載します。

React 知識

自分は React をよく知らないまま、開発に入りました。
なんかよくわからないけど、React.Component を継承してコンポーネント作っていけばいいんだな!
そこまでは既存コードを見れば、何となく分かりました。で Props と State が変化すれば画面も切り替わっていく。

しかし、思った通りのタイミングで描画ができません。
render メソッドが呼ばれないタイミングもあれば、逆に呼ばれまくって処理が重くなったり。
そのときの私は、ライフサイクルを理解していませんでした。

React component ライフサイクル図
(一部メソッドが廃止になってます: React.js のライフサイクルメソッド componentWillReceiveProps の廃止対応)

描画の問題はなんとかなりました。しかし、今度は画面間のデータ連携が上手くいかなくなります。
前の画面で入力されたデータを次のページに連携することは可能です。react-navigation を使ってパラメータを渡せば。
rearct native react-navigation 個人的メモ

しかし、2つ前の画面で設定されたデータを画面で表示するにはどうすればいいんだ..ということになり、
どこかにグローバル変数的にデータを持たせておき、参照するようにしました。
しかし、その定数を別画面が変更しても、Component 内のデータが変わっていないため、描画に変更が走りません。

どうすればいいんだー...と探し回り、出会ったのが、Redux でした。
Redux入門【ダイジェスト版】10分で理解するReduxの基礎

概念を理解するのは少し苦労しましたが、とっても便利です!
しかし、Redux では Reducer に「APIを呼び出す」ことをしてはいけない..と書かれています。
API の結果で状態を変えたい時はどうするんだ..とたどり着いたのが redux-saga というミドルウェアでした。(同じようなミドルウェアに redux-thunk, redux-promise があります)
redux-sagaで非同期処理と戦う
React + Reduxにおける非同期処理

ここまで分かって、実装である程度のことができる...と自信を持てるようになりました。

コンポーネント設計

一番最初、画面単位でコンポーネントを作っていました。(複雑だったら、分割すればいいよねー的なノリ)
そして、部品をコンポーネント化していくのですが、メンテナンスが上手くいかなかったです。

  • 似たようなコンポーネントの二重管理になる
  • コンポーネントがどのコンポーネントから使われているかわからない

似たようなコンポーネントの二重管理になる

2つの画面に似たものがあるけど、画面が違うことによって微妙に挙動が異なる。
そうなったときに、別にしてしまっていて、二重管理が発生している。

コンポーネントがどのコンポーネントから使われているかわからない

画面ごとに微妙にコンポーネントが違ってたりするときに、ある程度共通化するために
コンポーネントを作っていくと、コンポーネントの構造が全体として歪になります。
そうすると、コンポーネントがどのコンポーネントを使っているのか...ということが分かり辛くなります。

どうすればいいのか?

そこで、調べてみると、Atomic デザインというものに到達します。
Atomic Designを使ってReactコンポーネントを再設計した話

しかし、定義自体が明確ではなく、本当に考えずに適用すると苦しみます。
まず、Atom, Molecules, Organisms, Templates, Pages という5階層が基本ですが、
全ての画面をこのように組めというわけではありません。現実的には全て5階層で組むとかなり冗長な画面も発生します。

また、Atom は、最小単位ということで理解しやすいですが、
Molecules, Organisms の差はなんぞや?...ということが一番の問題です。
これに関しては、自分は明確に切ることができなかったので、

  • Organisms: それ単体でも業務的に意味のあるコンポーネント
  • Molecules: Atom を組み合わせてはあるけど、業務的に意味のないコンポーネント

という風に Molecules を Atom として作っておきたいけど、分離したものも必要だ!という場合に使っていました。
とはいえ、そんなケースを扱うことはほぼなかったので、Molecules はほとんどなかったです。

これにより、メンテナンス可能なアプリを作る自信が出てきました。

React native パッケージ

ReactNative では、様々な有名なパッケージがあります。例えば

この辺りのパッケージを知識として持っておけば、コストを最小にできると思います。
(また、出来るだけ要件をパッケージ側で実現できるように寄せられるとなお良し)

しかし、中には パッケージが管理されていないものもあります。
仮にそういったものを使うと、現バージョンの ReactNative で動くかどうかの検証、
いざ何か起こった時の対応というのがリスクとして存在します。

このため、昔の記事でよく紹介されていても、放置されているものは正直使い辛いです。
そんな時は作ってしまうのも一つの対策だと思います。

自身の経験では、評価する時の星(Rating)を画像に載せて欲しい、そのときに背景を透過色にして欲しい
という要望があったんですが、React Native Elementsでは対応できず、古いパッケージもちょっと怖い。
..ということで、自身でコンポーネントを作ったことがあります。

ReactNative バージョンに関する話

ReactNative バージョン上げるときは、結構覚悟を持ってやった方がいいです。
ReactNative は後方互換性は保証しません。また、そこそこ破壊的だと自分は思っています。

自分は(2019/8月ごろ)Androidの64bit対応が必要になり、バージョン(v0.57→v0.60にした)をあげました。(開発開始からAndroidアプリがアップロードできなくなるまで放置されていた)
コンパイルエラー出ていないか、機能が壊れていないか、デザインはどうか、iOS側に影響はないか...。

ReactNativeのAndroid 64bit対応時に読んでおきたいメモ

こちらのバージョンあげた理由は、「Androidアプリは64bitアプリしかできなくなった」
..っていう、理由でしたが、このように、ReactNative 上の理由以外にも、Apple, Google のポリシー変更によってバージョン上げざるを得ないことがあります。

古いバージョンで開発していると、大変な影響を受けることになります。
長くメンテナンスをするのであれば、バージョンアップはこまめにやりましょう...。

iOS/Androidアプリ構築に関する知識

ここまでは TypeScript で各部分のことに関して記載してきましたが、デプロイに関する話です。
まず、iOSアプリをリリースするのであれば、iOSの証明書周りは複雑ですが必須です。

[iPhone] iOS, Certificate 証明書を作ってみる

あと、顧客にテストビルドを見てもらうには下記の方法があります。

  • adhoc 証明書によるビルド
  • TestFlight を使う

ただし、TestFlight を使うには、AppleStore にアプリ登録が必要なので、
そこまでしたくない場合は、「adhoc 証明書によるビルド」を使うことになります。

Apple 側では、このようなテストアプリを不特定多数に提供されないためか?
起動できるDeviceIDの設定を証明書に含めています。この辺りを知らないと
提供したアプリが動かない、という事態に陥ります...。

基本的に Expo で作ってあれば、これ以降はあまり自分は嵌りませんでした。

Expo では、証明書は作ってくれますし、iOSアプリへの変換・Androidアプリの変換は
Expo側で行ってくれるので、この辺りの面倒ごとがかなり改善されます。

なのでもし、React Native CLI で開発する場合 (もしくは Expo で reject して開発する場合)は、

iOSのビルドに関する知識が必要です(xcode設定, Cocoapod, Build設定など)
また、Androidのビルド(gradle)に関する知識も必要です。

もし、ReactNative 側に package がインストールされていなかったりすると、
iOSアプリのビルド時にリファレンスエラーが出たりするので、ビルドエラーが起こったときは結構苦労します。

なので、自分は Expo 以外の開発は現在はほぼ行っていません。
ReactNative CLI を使うケースとしては、Expo で対応できない..というケースですが、
一般的なアプリはほぼそういった要件はありませんので。

仮にあったとしても、要件次第では Native アプリ(Swiftで)作ってかもしれません。

まとめ

ReactNative におよそ1年少し関わって、すごく苦労した話を中心に書きました。

ReactNative のいいところは、1つのソースコードから2つのプラットフォームを作れる手軽さです。
スモールスタートでアプリを作っていきたい、といった要望にはマッチすると思います。

パフォーマンスを求められるもの、最新技術を用いたい場合には、使い辛いですが、
選択肢の一つしては、これからも関わっていきたいと思います。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?