本書の翻訳は本日発行されますが、React Nativeを使用したユニバーサルアプリケーションの開発に関する小さなながらも非常に詳細なガイドです。
なぜこれだけなのですか?
「PWA」( プログレッシブWebアプリ 、プログレッシブWebアプリケーション)という今日の略語は誰にでもよく知られています。この3文字の頭字語は、技術用語の海のクジラのようです。 しかし、この人気のある技術にはまだ欠陥がないわけではありません。 このようなアプリケーションには多くの技術的な問題があり、開発者がネイティブアプリケーションとWebアプリケーションを同時に作成しなければならない場合があります。 PWAとネイティブアプリケーションを比較する良い記事があります。
おそらく、ビジネスはネイティブアプリケーションのみに焦点を合わせるべきでしょうか? いいえ、価値はありません。 これは大きな間違いです。 その結果、単一のユニバーサルアプリケーションの開発は論理的なステップになります。 これにより、開発時間を短縮し、プロジェクトの作成とサポートのコストを削減できます。 普遍的なアプリケーションのこれらの特性は、私に1つの小さな実験を促しました。
これは、食品を注文するための電子商取引の分野からの普遍的な応用例です。 実験の後、将来のプロジェクトとさらなる研究のためにテンプレートを作成しました。
パプは、Android、iOS、ウェブ向けに設計された食品注文アプリケーションです
アプリケーションの基本的な構成要素
ここではReactを使用しているため、アプリケーションロジックをユーザーインターフェイスから分離する必要があります。 ReduxやMobxなどのアプリケーションの状態を制御するには、何らかのシステムを使用するのが最善です。 そのような動きは、アプリケーション機能ロジックをすぐにユニバーサルにします。 変更することなく、異なるプラットフォームで使用できます。
アプリケーションの視覚的な部分は別の会話です。 アプリケーションインターフェイスを構築するには、基本的な基本要素であるユニバーサルのユニバーサルセットが必要です。 Webとネイティブ環境の両方で機能するはずです。 残念ながら、Webの言語とネイティブプラットフォームの言語は2つの異なるものです。
たとえば、標準のWebコンテナは次のように連絡します。
<div> ! - !</div>
そしてネイティブ-このように:
<View>! - React Native</View>
一部の賢い人々は、この状況から抜け出す方法を見つけました。 出力は特殊な要素ライブラリでした。 私のお気に入りの1つは、素晴らしいReact Native Webライブラリです。 アプリケーションの基本的なプリミティブを処理するだけでなく、Web上でReact Nativeコンポーネント(すべてのコンポーネントではありません!)を使用できるようにするだけでなく、さまざまなReact Native APIへのアクセスも可能にします。 それらの中には、
Geolocation
、
Platform
、
Animated
、
AsyncStorage
などがあります。 このライブラリのマニュアルにある素晴らしい例をご覧ください。
模様
プリミティブを見つけました。 ただし、Web開発とネイティブ開発のために環境を接続する必要があります。 私のプロジェクトでは、 create-react-app (Webアプリケーション用)とReact Native 初期化スクリプト (Expoなしのネイティブアプリケーション用)を使用しています。 最初に、このコマンドで1つのプロジェクトを作成しました:
create-react-app rnw_web
。 次に、2番目のプロジェクトである
react-native init raw_native
を作成しました。 次に、Victor Frankensteinの例に従って、これら2つのプロジェクトから
package.json
ファイルを取り出してマージしました。 その後、新しいプロジェクトのフォルダーで、新しい
yarn
ファイルをフィードしました。 問題の
package
ファイルは次のとおりです。
{ "name": "rnw_boilerplate", "version": "0.1.0", "private": true, "dependencies": { "react": "^16.5.1", "react-art": "^16.5.1", "react-dom": "^16.5.1", "react-native": "0.56.0", "react-native-web": "^0.9.0", "react-navigation": "^2.17.0", "react-router-dom": "^4.3.1", "react-router-modal": "^1.4.2" }, "devDependencies": { "babel-jest": "^23.4.0", "babel-preset-react-native": "^5", "jest": "^23.4.1", "react-scripts": "1.1.5", "react-test-renderer": "^16.3.1" }, "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start", "test": "jest", "start-ios": "react-native run-ios", "start-web": "react-scripts start", "build": "react-scripts build", "test-web": "react-scripts test --env=jsdom", "eject-web": "react-scripts eject" } }
このバージョンのファイルにはナビゲーション機能がないことに注意してください。 次に、すべてのソースファイルをWebアプリケーションとネイティブアプリケーションのフォルダーから新しい統合プロジェクトのフォルダーにコピーする必要があります。
新しいプロジェクトにコピーするフォルダー
次に、新しいプロジェクトのディレクトリにある
src
フォルダーに、
App.js
と
App.native.js
2つのファイルを作成します。 webpackのおかげで、ファイル名拡張子を使用して、どのファイルを使用するかをバンドラーに伝えることができます。 アプリケーションをナビゲートするためにさまざまなアプローチを使用するため、
App
ファイルを分離することは重要です。
これがWeb用の
App.js
ファイルです。
react-router
ナビゲーションに使用され
react-router
。
// App.js - WEB import React, { Component } from "react"; import { View } from "react-native"; import WebRoutesGenerator from "./NativeWebRouteWrapper/index"; import { ModalContainer } from "react-router-modal"; import HomeScreen from "./HomeScreen"; import TopNav from "./TopNav"; import SecondScreen from "./SecondScreen"; import UserScreen from "./UserScreen"; import DasModalScreen from "./DasModalScreen"; const routeMap = { Home: { component: HomeScreen, path: "/", exact: true }, Second: { component: SecondScreen, path: "/second" }, User: { component: UserScreen, path: "/user/:name?", exact: true }, DasModal: { component: DasModalScreen, path: "*/dasmodal", modal: true } }; class App extends Component { render() { return ( <View> <TopNav /> {WebRoutesGenerator({ routeMap })} <ModalContainer /> </View> ); } } export default App;
React Nativeアプリの
App.js
は次の
App.js
です。 ここで、
react-navigation
使用さ
react-navigation
ます。
// App.js - React Native import React, { Component } from "react"; import { createStackNavigator, createBottomTabNavigator } from "react-navigation"; import HomeScreen from "./HomeScreen"; import DasModalScreen from "./DasModalScreen"; import SecondScreen from "./SecondScreen"; import UserScreen from "./UserScreen"; const HomeStack = createStackNavigator({ Home: { screen: HomeScreen, navigationOptions: { title: "Home" } } }); const SecondStack = createStackNavigator({ Second: { screen: SecondScreen, navigationOptions: { title: "Second" } }, User: { screen: UserScreen, navigationOptions: { title: "User" } } }); const TabNav = createBottomTabNavigator({ Home: HomeStack, SecondStack: SecondStack }); const RootStack = createStackNavigator( { Main: TabNav, DasModal: DasModalScreen }, { mode: "modal", headerMode: "none" } ); class App extends Component { render() { return <RootStack />; } } export default App;
これが、私が簡単なアプリケーションテンプレートを作成し、さらに作業するためのプラットフォームを準備する方法です。 このリポジトリを見て、 このテンプレートを試すことができます。
次に、このテンプレートを少し複雑にし、ルーティング/ナビゲーションシステムを追加します。
ナビゲーションの問題とその解決策
アプリケーションが単一の画面で構成されていない場合、特定のナビゲーションシステムが必要です。 現在(2018年9月について話している)、Webアプリケーションとネイティブアプリケーションの両方に適した、このようなユニバーサルワーキングシステムは1つだけです。 これはReact Routerです。 Webの場合、このソリューションはうまく機能しますが、React Nativeプロジェクトの場合、すべてがそれほど明確ではありません。
React Router Nativeでは、画面間の遷移はなく、戻るボタン(Androidプラットフォーム用)のサポートもありません。モーダル画面、ナビゲーションバー、その他の機能もありません。 React Navigationなどの他のナビゲーションツールには、これらの機能があります。
私はこの特定のライブラリを使用しましたが、何か他のものを選択できます。 したがって、私のプロジェクトでは、React RouterはWebアプリケーションのナビゲーションを担当し、React Navigationはネイティブアプリケーションのナビゲーションを担当します。 ただし、これにより新しい問題が発生します。 実際、これらのシステムでのナビゲーションとパラメーターの転送のアプローチは非常に異なっています。
React Native Webの精神を維持するために、どこでもネイティブアプリケーションで使用されているのと同様のアプローチを使用して、Webルートを作成し、それらをHOCでラップすることでこの問題の解決に取り組みました。 これにより、React Navigationに似たAPIを作成できました。
このアプローチにより、Webアプリケーションの画面間を移動でき、2種類のアプリケーション用に個別のコンポーネントを作成する必要がなくなりました。
このメカニズムを実装する最初のステップは、Webアプリケーションのルートの説明を含むオブジェクトを作成することです。
import WebRoutesGenerator from "./NativeWebRouteWrapper"; // , React Router HOC const routeMap = { Home: { screen: HomeScreen, path: '/', exact: true }, Menu: { screen: MenuScreen, path: '/menu/sectionIndex?' } } // render <View> {WebRoutesGenerator({ routeMap })} </View>
実際、React Router固有の機能が追加されたReact Navigation作成関数のコピーがあります。
次に、ヘルパー関数を使用して、
react-router
ルートを作成し、HOCでラップします。 これにより、
screen
コンポーネントのクローンを作成し、そのプロパティに
navigation
を追加できます。 このアプローチは、React Navigationの動作を模倣し、
navigate()
、
goBack()
、
getParam()
などのメソッドを
getParam()
。
モーダルスクリーン
React Navigationは、
createStackNavigator
おかげで、アプリケーションの特定のページをモーダル画面の形で下からポップすることを可能にします。 Webアプリケーションでこれを実現するには、 React Router Modalライブラリを使用する必要がありました。 モーダル画面を使用するには、まず適切なオプションを
routeMap
オブジェクトに追加する必要があります。
const routeMap = { Modal: { screen: ModalScreen, path: '*/modal', modal: true // ModalRoute } }
さらに、
react-router-modal
ライブラリの
<ModalContainer />
コンポーネントをアプリケーションレイアウトに追加する必要があります。 対応するページがそこに表示されます。
画面間のナビゲーション
開発のHOC(一時的にこのコンポーネントは
NativeWebRouteWrapper
と呼ばれ、これはひどい名前です)のおかげで、React Navigationとほぼ同じ機能セットを使用して、Webバージョンのアプリケーション内のページ間の移動を整理できます。
const { product, navigation } = this.props <Button onPress={navigation.navigate('ProductScreen', {id: product.id})} title={`Go to ${product.name}`} /> <Button onPress={navigation.goBack} title="Go Back" />
前の画面に戻ります。
React Navigationでは、ナビゲーションスタックにある
n
画面に戻ることができます。 同様のReact Routerは利用できません。ナビゲーションスタックはありません。 この問題を解決するには、独自のデザインの
pop
関数をコードにインポートする必要があります。 彼女を呼び出して、私たちは彼女にいくつかのパラメーターを与えます:
import pop from '/NativeWebRouteWrapper/pop' render() { const { navigation } = this.props return ( <Button onPress={pop({screen: 'FirstScreen', n: 2, navigation})} title="Go back two screens" /> ) }
これらのパラメーターについて説明します。
- screen-
screen
名(WebバージョンのアプリケーションでReact Routerが使用)。 -
n
は、スタックを使用して返される画面の数です(React Navigationを使用)。 -
navigation
-navigation
を提供するオブジェクト。
作業結果
ここで紹介するユニバーサルアプリケーションを開発するというアイデアを試してみたい場合は、2つのテンプレートを作成しました。
1つは、Webアプリケーションとネイティブアプリケーションを開発するためのクリーンでユニバーサルな環境です。
2つ目は、本質的には、最初のテンプレートです。このテンプレートは、アプリケーション内のナビゲーションを整理するためのシステムにより拡張されています。
上記の考慮事項に基づいたpapuデモアプリケーションを次に示します。 エラーや行き止まりがたくさんありますが、自分で組み立てて、ブラウザやモバイルデバイスで実行し、実際にすべてがどのように機能するかを知ることができます。
まとめ
もちろん、React開発者コミュニティには、アプリケーションナビゲーションを整理するためのユニバーサルライブラリが必要です。これにより、先ほど説明したようなプロジェクトの開発が簡単になります。 React NavigationライブラリがWeb上で動作する場合、非常に便利です(実際、この機能は既に利用可能ですが 、それを使用するのに困難はありません)。
親愛なる読者! Reactを利用してユニバーサルアプリケーションを作成していますか?