LoginSignup
5

More than 1 year has passed since last update.

posted at

updated at

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

この記事は「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つのプラットフォームを作れる手軽さです。
スモールスタートでアプリを作っていきたい、といった要望にはマッチすると思います。

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

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
What you can do with signing up
5