🗂

Expoで素のReact Componentを表示する(ガラネィティブ編)

2022/07/18に公開

Expoでアウトライナー(WorkFlowyとか、Dynalistみたいなの)を作ろうと思いたち、良さげなコンポーネントを探してはみたものの残念ながらピッタリのものは見つからなかった。

惜しいことに素のReactComponentなら「react-outliner」があったのだが、ReactNativeComponentではないためExpoでは直接使用できない。ぐぬぬ。

https://github.com/ashleydavis/react-outliner

ならばとReactComponentである「react-outliner」は通常のReactをWebアプリケーションとして起動しておき、Expoで作ったマルチプラットフォームアプリからはWebView経由でWebアプリに繋ぎに行って画面表示する作戦を取ることにした。
これならExpo製のAndroidアプリやデスクトップアプリでも素のReactComponentを使用できる(ように見える)

これがうまくいくなら開発コストが低いExpoで、リッチなReactコンポーネントを使って簡単にデスクトップアプリを作れる・・・という扉が開かれることになるかもです。(ただ実行にはWebアプリ側の起動が必要なので、用途は限られそう)

目標

  • 1プロジェクト内でReactのWebアプリケーションとExpoのプロジェクトを共存させる(「react-outliner」はライブラリのバージョンに思ったより厳しかったので、今思うとプロジェクト分けても良かった)
  • 「react-outliner」は公式のexsampleをそのまま表示し、Expo製アプリで素のReactComponentが使用できることを確認するところまでを今回のゴールとする
  • アプリはAndroid、Desktopそれぞれで試す

プロジェクトのひな形作成

まずはExpoでプロジェクトのひな形を作成

expo init gara-native --template @native-base/expo-template;
cd gara-native;

Webアプリの作成

元ネタのライブデモを確認する

react-outlinerはライブデモもあります。
このイメージがモバイルアプリやデスクトップでそのまま動いてくれればゴールです。

ソースの取得と配置

react-outlinerのgithubのダッシュボードの記載通りに指定しても型エラーで動かなかった。ソースの「react-outliner/example」以下に配置されたコードを参考にすると動いた。

ソースの取得先

react-outlinerは、バージョンの組み合わせに敏感なので先にpackage.jsonを修正してから、yarnを実行してパッケージインストールするのがよい

実際に変更したファイルは以下

package.json
(scripts)を修正
    "web": "react-scripts start",
    ※webアプリはexpoで動かさないため
    
(dependenciesに下記を反映)
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    ※^をつけないとreact-outlinerが動かなかった

    "react-outliner": "0.0.9",
    "react-scripts": "4.0.1"
    ※このバージョン固定出ないとreact-outlinerが動かなかった  

ソース取得元のexsampleフォルダ以下のファイルを、下記フォルダ構成で配置
public/index.html
src/App.css
src/App.js
src/index.css
src/index.js

Webアプリケーションの実行

下記コマンドでパッケージのインストールとWebアプリの起動を行う

yarn;
yarn web;

ライブデモと同じ画面が出れば成功!

Android用アプリの作成

Expo側はWebViewを使うことになるが、なかなか難しい状況のようだ。

ExpoのWebView(react-native-webview)を使用する

https://docs.expo.dev/versions/latest/sdk/webview/

ExpoのWebViewは、Androidからの利用はOKだがWebアプリからの利用は不可とのこと。

今回のWebアプリはExpoを使わないので、ExpoのWebViewをそのまま使います。(Androidは確かに問題なかったのですが・・・後述で再びこの話題に触れます)

ExpoのWebアプリでWebViewを使う場合は、「react-native-web-webview」を使います。
こちらの記事が参考になりました。
https://qiita.com/yosukesuzuki/items/96e41eb1b75a2271df0d

もう一つ気合の入ったプロダクトで、HTMLをパースしてReactNative用にレンダリングする正面突破を行っている「react-native-render-html」がありました。
HTMLのパースが必要だったり、パフォーマンス要求が厳しい場合に助かりそうです。
https://meliorence.github.io/react-native-render-html/docs/content/textual

package.jsonを修正して、yarnを実行してパッケージインストールします。

package.json
(dependenciesに下記を反映)
    "react-native-web-webview": "^1.0.2",
    "react-native-webview": "11.15.0",

App.jsの修正

App.js
import React from "react";
import { WebView } from "react-native-webview";

export default function App() {
  return (
    <WebView
      originWhitelist={['*']}
      source={{ uri: "http://〔WEBサーバのIPアドレス〕:3000" }}
    />
  );
}

URLには、AndroidからアクセスできるようにWEBサーバのIPアドレスを設定してください。

Webサーバが起動していることを確認後、
別のコンソールでyarn startを実行して、AndroidのExpoからScan QRcodeでAndroidアプリを実行してください。


Androidでガラネイティブ

AndroidのExpoアプリで、素のReactComponentが動きました!

デスクトップアプリの作成

Webアプリ用のWebView(react-native-web-webview)を使用する

動かしてみて分かったことですが、ElctronでExpo標準のViewを動かすと何も表示されませんでした。内部的にWebアプリケーションと評価されているのかもしれません。
そういう時は、先ほどの「react-native-web-webview」の登場です。

https://qiita.com/yosukesuzuki/items/96e41eb1b75a2271df0d

App.js
import React from "react";
// import { WebView } from "react-native-webview";
import { WebView } from "react-native-web-webview";

}

Android使用時は"react-native-webview"を使い、Electron使用時は"react-native-web-webview"を使い分けることになります。

今回は対応しませんでしたが、エイリアスを設定して、プラットフォームで参照先を切り替えるようにすれば回避できそう。
https://chaika.hatenablog.com/entry/2018/12/14/120000

Electronでデスクトップアプリを実行

yarn
yarn add -D @expo/electron-adapter
yarn expo-electron
yarn expo-electron start


デスクトップでガラネイティブ

動いた!

Discussion