toshi-toma blog

主にフロントエンド、作業ログあとは色々なメモ ✍️ 🍅

React Native for Webを触ってみた

React Native for Webという言葉はよく耳にしていましたが、具体的にどういうものなのか知らなかったので、触ってみました。

React Native for Web

necolas.github.io

「React Native for Web」は、React NativeパッケージのコンポーネントAPIで書かれたコードを、Webでも動かせるように、Web用にコンポーネントAPIを提供しているライブラリ。 パッケージはreact-native-web

React Nativeでコンポーネントを作ると以下のようなコードになる。

import React from "react";
import { StyleSheet, Text, View } from "react-native";

function App() {
  return (
    <View style={styles.app}>
        <Text style={styles.title}>React Native</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  app: {
    marginHorizontal: "auto",
    maxWidth: 500
  },
  title: {
    fontWeight: "bold",
    fontSize: "1.5rem",
    marginVertical: "1em",
    textAlign: "center"
  },
});

export default App;

ここで利用している、StyleSheet, Text, Viewといったコンポーネントが、react-native-webパッケージで、Webのコードでexportされている。

react-native-web/packages/react-native-web/src/exports at master · necolas/react-native-web · GitHub

なので、webpackのresolve.aliasで、importのreact-nativereact-native-webに置き換えれば、全く同じコードでそのままwebでも動く。

// webpack.config.js
module.exports = {
  resolve: {
    alias: {
      'react-native$': 'react-native-web'
    }
  }
}

コンポーネント

react-nativeと同じ名前やpropsを持つコンポーネントがexportされていて、内部ではReact DOMでReact Nativeっぽい見た目や動きのものを実装してる

API

コンポーネント以外にも、react-nativeで公開されているAPIも提供している。 例えば、Share APIはreact-native-webでは、window.navigator.shareで実装されている

いいところ

React Nativeで作ったコードが、読み込むパッケージが違うだけで、ネイティブアプリでもWebでも動くので、共通化できるのが良いポイント。 iOS, Android, Webでアプリを提供したい場合に、とても良さそう。

その他

  • StyleSheetはCSS-in-JSと同じでコンポーネントごとにhash付きのclass名が付与されて、headのstyleタグに吐き出される感じっぽい
  • Platform.OSはwebが入るので、コンポーネントの出し分けも可能

セットアップ

セットアップは簡単で、必要なパッケージをインストールして、webpackのaliasの設定をするだけ。

  • 必要なパッケージ
    • react-dom
    • react-native-web
    • babel-plugin-react-native-web
      • 無くても動く
      • ビルドの最適化のためにおすすめってドキュメントには書いてある
  • パッケージをインストールしたら、webpackのaliasでreact-nativeをreact-native-webに置き換えるだけ

create-react-app

create-react-appでreact-native-webパッケージを入れたらとりあえず動いた。React Native for Webをデフォルトでサポートしてるっぽい。 create-react-appのwebpackの設定を確認したところ、デフォルトでwebpackのaliasが入ってるから動くようになっている。

github.com

公式ドキュメントではExpoを推奨してる。

サポートされているコンポーネント

以下のページを見たら良い

React Native compatibility // React Native for Web

その他参考