React Nativeが発表されたとき、最初の反応は圧倒的にポジティブでした。従来、モバイル空間のWebテクノロジーについて考えると、次のようなものがあります。 Apacheコルドバ これにより、WebサイトまたはWebアプリケーションをモバイルプラットフォーム用のアプリケーションとしてパッケージ化できるようになります。この初心者向けチュートリアルでは、React Nativeのアーキテクチャ、React Nativeの背後にある哲学、および同じスペース内の他のソリューションとの違いについて説明します。記事の終わりまでに、Reactの「HelloWorld」アプリケーションをReactNativeアプリケーションに変換します。
それを言うことから始めましょう リアクトネイティブ は比較的新しいテクノロジーです。 2015年3月から正式に利用可能になり、その年の初めからプライベートベータ版であり、それ以前はFacebookでしばらく社内で使用されていました。 「ローマは一日にして成らず」ということわざは、一般的にテクノロジーにも当てはまります。 grunt
のようなツールNode.jsのようなプラットフォームは成熟するのに何年もかかりました。 Webの世界では、物事は急速に進んでおり、膨大な数のフレームワーク、パッケージ、およびツールが毎日出てきています。 開発者 少し懐疑的になる傾向があり、すべての誇大広告の時流に飛び乗って、ベンダーロックインの状況に陥ったことに気付くだけではありません。 React Nativeが特別な理由、それが参加する価値のあるテクノロジーである理由について説明し、すべてがユニコーンやレインボーではないいくつかの例について説明します。
モバイルでのWebテクノロジーについて話すとき、利用可能なソリューションは通常、次のいずれかのカテゴリに分類されます。
Webアプリケーションは、通常WebViewと呼ばれるモバイルブラウザに存在します。大きなリファクタリングがなくても、WebサイトまたはWebアプリケーションはモバイルデバイスで動作します。完全なユーザーエクスペリエンスを実現するには、デバイスの向きの変更をタップしたり聞いたりするなどのモバイルブラウザイベントや小さな画面を考慮する必要があるかもしれませんが、最小限の労力でモバイルバージョンを使用できます。 Cordova / PhoneGapは、このカテゴリで最も人気のあるオプションです。残念ながら、このオプションには大きな欠点があります。場合によっては、Cordovaを使用して開発されたアプリケーションは、特にグラフィックが多いアプリケーションの場合、ネイティブアプリケーションよりも大幅に遅くなります。その他の場合、モバイルオペレーティングシステムは、モバイルブラウザで利用できるWebViewのすべての機能を実際に提供しているわけではありません。ユーザーエクスペリエンスもネイティブアプリケーションとは異なる場合があります。これは、アプリケーションまたはプラットフォーム自体が原因で発生する可能性があります。この問題は、スクロールバーが同じように感じられないことから、要素をタップするときに目立った遅延が発生することまでさまざまです。
まったく異なる解決策は、最終的にネイティブコードベースを作成することです。これは、元のソースコードを別のプログラミング言語に変換することで発生します。ネイティブパフォーマンスを、いくつかの不確実性を伴う抽象化レイヤーと交換します。クローズドソースソリューションの場合、内部で何が起こっているのか、どのようなブラックボックスを扱っているのかさえわかりません。その他の場合、次のモバイルオペレーティングシステムの更新によってコードがどの程度破損するか、修正または更新がいつ利用可能になるかがわかりません。このカテゴリの人気のある例は Haxe 。
ここでは、モバイル環境のJavaScriptエンジンを使用して、そこでJavaScriptを実行します。ネイティブコントロールはJavaScriptオブジェクトと関数にマップされているため、fancyButtonRightHere()
という関数を呼び出すと、画面にボタンが表示されます。 NativeScriptまたはAppceleratorTitaniumは、このカテゴリのよく知られた例です。
React Nativeは、3番目のカテゴリーからのものとして分類できます。 iOSおよびAndroidバージョンの場合、React Nativeは内部でJavaScriptCoreを使用します。これは、iOSのデフォルトのJavaScriptエンジンです。 JavaScriptCoreは、AppleのSafariブラウザのJavaScriptエンジンでもあります。 OSXと iOS開発者 彼らが望むなら、実際にそれと直接インターフェースすることができます。
大きな違いの1つは、 リアクトネイティブ JavaScriptコードを別のスレッドで実行するため、ユーザーインターフェイスがブロックされることはなく、アニメーションは滑らかでスムーズである必要があります。
ReactNativeの「React」が誤ってそこに置かれていないことは注目に値します。 React Nativeの場合、Reactが提供するものを正確に理解する必要があります。以下の概念は、ReactとReact Nativeの両方で同じように機能しますが、これらのコード例はブラウザーで実行するように調整されています。
単純なReactコンポーネントを見ると、最初に気付くのは、コンポーネントにrender
があることです。関数。実際、コンポーネント内にレンダリング関数が定義されていない場合、Reactはエラーをスローします。
var MyComponent = function() { this.render = function() { // Render something here }; };
特別なことは、ここではDOM要素をいじらないことですが、DOMでレンダリングされるものを表すXMLベースの構造を返します。このXMLベースの構造はJSXと呼ばれます。
var MyComponent = function() { this.render = function() { return Hello there ; }; };
特別なJSXトランスフォーマーは、そのXMLに見えるコードをすべて受け取り、それを関数に変換します。変換後のコンポーネントは次のようになります。
var MyComponent = function() { this.render = function() { return React.createElement('div', { className: 'my-component' }, 'Hello there'); }; };
最大の利点は、コンポーネントをざっと見ることで、コンポーネントが何をするのかを常に把握できることです。たとえば、acomponentはいくつかのコンポーネントをレンダリングする場合があります。コンポーネントをrender
内以外の場所にレンダリングすることはできません。関数なので、レンダリングされたコンポーネントがどこから来たのか正確にわからないという心配はありません。
コンポーネントのコンテンツを構築するために、Reactはプロパティまたは小道具を略して提供します。 XML属性と同様に、小道具をコンポーネントに直接渡し、構築されたコンポーネント内で小道具を使用できます。
var Hello = function(props) { this.render = function() { return Hello {props.name} ; }; }; var Greeter = function() { this.render = function() { return } };
これにより、コンポーネントがツリーのような構造になり、子要素を作成するときにのみデータを渡すことができます。
小道具に加えて、コンポーネントは内部状態を持つこともできます。その動作の最も顕著な例は、ボタンが押されたときにその値を更新するクリックカウンターです。クリック数自体が状態に保存されます。
小道具と状態の変化のそれぞれが、コンポーネントの完全な再レンダリングをトリガーします。
小道具や状態が変化したときにすべてが再レンダリングされると、なぜReact自体がそれをうまく実行しているのでしょうか。魔法の要素は「仮想DOM」です。何かを再レンダリングする必要があるときはいつでも、更新されたDOMの仮想表現が生成されます。仮想DOMは、コンポーネントツリーをモデルにした要素の軽い表現で構成されているため、実際のDOM要素を生成するよりもはるかに効率的に要素を生成できます。変更を実際のDOMに適用する前に、コンポーネントツリーのどこで変更が発生したかを正確に判断するためのチェックが行われ、差分が作成され、それらの特定の変更のみが適用されます。
デザインバランス定義の原則
初心者がReactNative用に開発するために設定する必要がある特定の前提条件があります。 iOSがサポートされた最初のプラットフォームであり、このチュートリアルで取り上げているプラットフォームであるため、少なくともバージョン6.3のmacOSとXcodeが必要です。 Node.jsも必要です。役立つのはインストールです 警備員 brew install watchman
を使用してBrewパッケージマネージャーを介して。これは必ずしも必要ではありませんが、ReactNativeプロジェクト内の多くのファイルを処理するときに役立ちます。
React Nativeをインストールするには、次のことを行うだけです。 ReactNativeコマンドラインアプリケーションをインストールします npm install -g react-native-cli
で。 react-native
を呼び出すコマンドは、新しいReactNativeアプリケーションの作成に役立ちます。実行中react-native init HelloWorld
HelloWorld
というフォルダを作成しますボイラープレートコードを見つけることができます。
Reactが主要な機能であり、Reactライブラリのコア原則であるため、最小限のReact「HelloWorld」アプリケーションをReactNativeアプリケーションに変換するために必要なものを見てみましょう。
このコード例では、いくつかのES2015機能、特にクラスを使用しています。 React.createClass
に固執することは完全に実行可能ですまたは、一般的なモジュールパターンと同様の関数フォームを使用します。
var React = require('react'); class HelloThere extends React.Component { clickMe() { alert('Hi!'); } render() { return ( Hello {this.props.name}. Please click me. ); } } React.render(, document.getElementById('content'));
最初のステップでは、Reactモジュールがreact-native
を使用するように変更する必要があります。代わりに。
var React = require('react-native'); class HelloThere extends React.Component { clickMe() { alert('Hi!'); } render() { return ( Hello {this.props.name}. Please click me. ); } } React.render(, document.getElementById('content'));
React Webアプリケーションを開発するときに通常ツールパイプラインの一部となるのは、ReactNativeの不可欠な部分です。
当然のことながら、モバイルにはDOMはありません。以前に使用した場所で使用する必要があり、を使用した場所で、ここで必要なコンポーネントはです。
import React from ‘react'; import {View, Text, Alert} from ‘react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert(‘hi!'); } render() { return ( Hello {this.props.name}. Please click me. ); } } React.render(, document.getElementById('content'));
テキストを要素に直接配置するのは非常に便利ですが、ネイティブの世界ではテキストをに直接配置することはできません。そのためには、コンポーネントを挿入する必要があります。
import React from ‘react'; import {View, Text, Alert} from ‘react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert(‘hi!'); } render() { return ( Hello {this.props.name}. Please click me. ); } } React.render(, document.getElementById('content'));
React Nativeを使用すると、float
をいじる代わりに、Flexboxモデリングを使用できます。およびinline-block
私たちはウェブの世界でとてもよく知っています。興味深いのは、ReactNativeがCSSを使用しないことです。
s法人vs.c法人
import React from ‘react'; import {View, Text, StyleSheet, Alert} from ‘react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert(‘hi!'); } render() { return ( Hello {this.props.name}. Please click me. ); } } var styles = StyleSheet.create({ box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 } }); React.render(, document.getElementById('content'));
インラインスタイルの使用は、初心者には戸惑うようです。これは、JSXに直面し、以前はハンドルバーやジェイドなどのテンプレートエンジンを使用していたときにReact開発者が経験しなければならなかった移行に似ています。
アイデアは、CSSを使用する方法でグローバルにスタイルシートを持っていないということです。スタイルシートはコンポーネントレベルで直接宣言するため、コンポーネントの機能、作成するレイアウト、および適用するスタイルを確認するために必要なすべての情報があります。
import React from ‘react'; import {Text} from ‘react-native'; var Headline = function(props) { this.render = () => {props.caption}; }; var headlineStyles = StyleSheet.create({ text: { fontSize: 32, fontWeight: 'bold' } }); module.exports = Headline;
Webページをクリックするのと同じことは、モバイルデバイスの要素をタップすることです。要素をタップすると「アラート」がポップアップするようにコードを変更しましょう。
import React from ‘react'; import {View, Text, StyleSheet, TouchableOpacity, Alert} from ‘react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert('Hi!') } render() { return ( Hello {this.props.name}. Please click me. ); } } var styles = StyleSheet.create({ box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 } }); React.render(, document.getElementById('content'));
コンポーネントでイベントを直接利用できる代わりに、イベントをトリガーする要素を明示的に使用する必要があります。この場合は、ビューを押したときのタッチイベントです。利用可能なタッチ可能なコンポーネントにはさまざまなタイプがあり、それぞれが異なる視覚的フィードバックを提供します。
Platform.OS
の値にアクセスすることで、ReactNativeアプリケーションが実行されているプラットフォームを検出できます。上記の例で、実行しているプラットフォームに基づいて異なるアラートメッセージを表示したいとします。私たちはこのようにそれを行うことができます:
... clickMe() { var message = ‘'; if(Platform.OS == ‘ios') { message = ‘Welcome to iOS!'; } else if(Platform.OS == ‘android') { message = ‘Welcome to Android!'; } Alert.alert(message); } ...
または、select
スイッチのような構文を提供するメソッドも利用できます。
… clickMe() { Alert.alert(Platform.select({ ios: ‘Welcome to iOS!', android: ‘Welcome to Android!' }) ); } ...
react-native link
カスタムフォントを追加するには、いくつかのフープをジャンプする必要があります。まず、フォントのフルネームとフォントのファイル名が同じであることを確認します。iOSはフォントを取得するためにフォントのフルネームを使用しますが、Androidはファイル名を使用します。
したがって、フォントのフルネームがmyCustomFont
の場合は、フォントのファイル名がmyCustomFont.ttf
であることを確認してください。
その後、assetsフォルダーを作成し、npmをポイントする必要があります。最初にassets/fonts
の下にフォルダを作成することでそれを行うことができますアプリケーションのルートディレクトリにあります。他のディレクトリでもかまいませんが、これはfontsディレクトリに使用される従来の名前です。
Assets
を追加することで、アセットの場所をnpmに伝えることができます。 Reactのnpm統合セクションのプロパティrnpm:
'rnpm': { 'Assets': [ './assets/fonts/' ] }
これらすべてを実行した後、最終的にreact-native link
を実行できます。これにより、フォントが適切なディレクトリにコピーされ、iOSのinfo.plistに必要なxmlが追加されます。
完了したら、任意のスタイルシートでフルネームで参照するだけでフォントを使用できます。 Text
で使用しましょう素子:
import React from ‘react'; import {View, Text, StyleSheet, TouchableOpacity, Alert} from ‘react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert('Hi!') } render() { return ( Hello {this.props.name}. Please click me. ); } } var styles = StyleSheet.create({ box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 }, message: { fontFamily: 'myCustomFont' } }); React.render(, document.getElementById('content'));
React Nativeは、コンポーネントのレイアウトにFlexboxと同じルールを使用します。ボタンを画面の下部に配置したいとします。TouchableOpacity
をラップしましょうコンテナ付きView
:
Hello {this.props.name}. Please click me.
それでは、container
を定義しましょう。スタイル、および他のすでに定義されたスタイルと一緒に:
container: { flex: 1, justifyContent: 'center', alignItems: 'center' }
justifyContent
に焦点を当てましょうおよびalignItems
。これらの2つのプロパティは、コンポーネントがそれぞれ一次軸と二次軸に沿ってどのように配置されるかを制御します。デフォルトでは、主軸は垂直軸であり、副軸は水平軸です(flexDirection
プロパティをrow
に設定することで変更できます)。
justifyContent
次のように設定できる6つの可能な値があります。
flex-start
コンポーネントのバウンディングボックスの先頭に、すべての要素を一緒に配置します。flex-end
すべての要素を最後に配置します。center
すべての要素をバウンディングボックスの中央に配置します。space-around
コンポーネントを均等に広げ、作成されたバウンディングボックスの中央に配置します。space-evenly
コンポーネントも均等に分散しますが、コンポーネントと他の境界の間に同じ量のスペースを残そうとします。space-between
隣接するコンポーネント間の間隔を等しく保つことにより、コンポーネントを広げます。alignItems
flex-start
、flex-end
、center
、およびstretch
の4つの可能な値に設定できます。最初の3つは、justifyContent
の場合と同じように動作しますが、stretch
軸に沿って使用可能なすべてのスペースを占めるようにコンポーネントを設定し、軸が完全に満たされるようにします。
つまり、TouchableOpacity
が必要なので下部に表示され、横軸の中央に表示されるようにするには、次のようにスタイルを変更できます。
container: { flex: 1, justifyContent: 'flex-end', alignItems: 'center' }
値の詳細justifyContent
およびalignItems
見つけることができます ここに そして ここに 。
ブラウザー用にReactを使用して開発する場合は、マウントポイントを定義し、React.render
を呼び出して、Reactにその魔法を実行させるだけです。 React Nativeでは、これは少し異なります。
import React from ‘react'; import {View, Text, StyleSheet, TouchableOpacity, Alert, Platform} from ‘react-native'; class HelloThere extends React.Component { clickMe() { Alert.alert(Platform.select({ ios: ‘Welcome to iOS!', android: ‘Welcome to Android!' })); } render() { return ( Hello {this.props.name}. Please click me. ); } } var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'flex-start', alignItems: 'center' }, box: { borderColor: 'red', backgroundColor: '#fff', borderWidth: 1, padding: 10, width: 100, height: 100 }, message: { fontFamily: 'myCustomFont' } }); var MainComponent = function() { this.render = function() { return ; } }; AppRegistry.registerComponent('MainComponent', function() { return MainComponent; });
AppRegistry
を使用して、Objective-C側のコンポーネントを登録する必要があります。オブジェクト。私たちが与える名前は、Xcodeプロジェクト内の名前と一致する必要があります。
Hello World React Nativeアプリケーションには、対応するWebアプリケーションよりも大幅に多くのコード行がありますが、一方で、React Nativeは、特にスタイルがコンポーネントで定義されているため、関心の分離をもう少し進めます。
ちなみに、clickMe
を再バインドしないでください。 this
へのメソッドrender
のコンテキスト特にReact(Native)アプリケーションが少し複雑になった場合は特にそうです。これは、非常に多くなる可能性のあるすべてのレンダリング呼び出しでメソッドを再バインドします。別の方法は、コンストラクター内でメソッドをバインドすることです。
アプリケーションを実行するには、index.ios.js
の内容を置き換える必要があります最後のステップから変換されたアプリケーションのコードの一部をファイルします。次に、Xcodeプロジェクトを開いて、大きな[実行]ボタンを押すだけです。まず、React Nativeサーバーでターミナルが開き、シミュレーターウィンドウが表示されます。 React Nativeサーバーはバンドルを作成し、ネイティブアプリケーションがそれをフェッチします。これにより、Web開発のような迅速な開発サイクルが可能になり、変更はほぼ瞬時にシミュレーターに反映されます。
Androidの場合、package.json
に以下を追加するだけで十分です。ファイル、scripts
の下:
'android-linux': 'react-native bundle --platform android --dev false --entry-file index.ios.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/ main/res && react-native run-android'
次に、npm run android-linux
を実行します。 android/app/src/main/assets
を確認してくださいディレクトリは事前に存在します。
ターミナルがポップアップすると、アプリケーションがシミュレーターに表示されます。 CMD + Dを押すと、開発メニューが表示されます。ボックスをクリックすると、アラートが表示されます。 iOSバージョン:
そしてAndroidは次のようなものをレンダリングします:
配布の場合、ローカル開発サーバーを指すアプリケーションを使用してもうまくいきません。このため、コマンドreact-native bundle
を使用して、ReactNativeサーバーが実行されていないときに使用するバンドルを作成できます。その場合、didFinishLaunchingWithOptions
を更新する必要がありますAppDelegate
の方法オフラインバンドルを使用します。
このサンプルアプリケーションも Githubで入手可能 。
言及する価値のあるもう1つの点は、モバイルアプリケーションにReactの概念とJavaScriptを使用するだけでなく、Web開発者が慣れているワークフローの一部をReactNativeでも使用できることです。 Web開発から来るとき、私たちはツールの開発、要素の検査、ライブリロードに慣れています。
React Nativeが機能する方法は、すべてのJavaScriptファイルをバンドルに入れることです。このバンドルは、サーバーから提供されるか、アプリケーションと一緒にバンドルされます。 1つ目は、ライブリロードを有効にできるため、シミュレータでの開発に非常に役立ちます。 Reactが提供する開発者メニューはChrome開発者ツールほど強力ではありませんが、ライブリロードと非常にWebのような開発者エクスペリエンスを提供します。 デバッグ Chrome(またはSafari)開発者/デバッガーツールを使用します。
Web開発者は、迅速なWebテストのためのオンラインプレイグラウンドであるJSFiddleまたはJSBinに精通しています。有る 同様の環境 これにより、WebブラウザーでReactNativeを試すことができます。
私は当初、ReactNativeに対してより慎重なアプローチを提案していました。今日、それは成熟した確かな選択です。
Reactの大きな利点の1つは、ビューレイヤーを表すだけなので、ワークフローに影響を与えないことです。独自のGruntパイプラインを定義しますか?それともWebpackを使用しますか?また、モデルのニーズにBackbone.jsを使用しますか?それとも、プレーンなJavaScriptオブジェクトを使用しますか? Reactはこれらの選択に制限を設けていないため、これらすべての質問への回答は完全にあなた次第です。公式サイトによると、「Reactは残りのテクノロジースタックについて何も想定していないため、既存のプロジェクトの小さな機能で簡単に試すことができます。」
ある程度、これはReactNativeにも当てはまります。モバイル開発者は、アプリケーションの一部としてReact Nativeを統合し、Webに触発された開発ワークフローを利用し、必要に応じてライブラリをより大規模に統合することを選択できます。
いずれにせよ、確かなことが1つあります。 ReactNativeはなくなることはありません 。 Facebookは、アプリストアに複数のReactNativeを利用したアプリケーションを持っていることに大きな利害関係を持っています。 React Nativeを取り巻くコミュニティは巨大であり、成長を続けています。
javascriptは日付をUTCタイムスタンプに変換します関連: QRスキャナーの構築:React NativeCameraチュートリアル
React Nativeは、JavaScriptを使用してネイティブiOSおよびAndroidアプリケーションを構築するためのフレームワークです。 Reactと同じ概念に基づいていますが、Webコンポーネントの代わりにネイティブコンポーネントを使用してユーザーインターフェイス(UI)をレンダリングします。
ReactはフロントエンドのJavaScriptライブラリであり、効率と予測可能性のために宣言型ビューを使用するという概念に基づいて設計されています。
複数のプラットフォームをサポートしている場合、React Nativeは、アプリのコアコードを再利用するという点で確かな利点があります。プラットフォーム固有のコードを提供する必要がある場合もありますが、プラットフォームごとにネイティブアプリを作成した場合よりも、作成と保守が少なくなります。
ネイティブアプリは、ターゲットプラットフォーム用にコンパイルされ、そのプラットフォーム上で直接実行されるアプリです。デフォルトでは、プラットフォームに適合する「ルックアンドフィール」があります。 React Nativeは、これと同じネイティブのルックアンドフィールを提供すると同時に、追加の移植性と使い慣れた方法論を提供することを目的としています。