メインコンテンツへスキップ

サンフランシスコミートアップのレポート

·9分で読めます
Héctor Ramos
エクトル・ラモス
元Facebook デベロッパーアドボケイト

先週、Zynga のサンフランシスコオフィスで開催された React Native ミートアップに参加する機会がありました。約 200 人が参加し、私と同じく React Native に興味を持っている他の開発者と出会うのに素晴らしい場所でした。

私は特に、Zynga、Netflix、Airbnbといった企業でReactとReact Nativeがどのように使われているかについて学ぶことに興味がありました。その夜のアジェンダは以下の通りでした。

  • Reactにおけるラピッドプロトタイピング
  • React NativeのためのAPI設計
  • ギャップを埋める:既存のコードベースでReact Nativeを使用する

しかし、まずイベントは簡単な紹介と最近のニュースの簡単な要約から始まりました。

もしこれらのミートアップのいずれかがあなたの近くで開催されるなら、ぜひ参加することをおすすめします!

ZyngaでのReactにおけるラピッドプロトタイピング

最初のニュース発表の後、今夜のホストである Zynga から簡単な紹介がありました。アビシェク・チャダは、彼らが React をどのように使ってモバイルで新しい体験を素早くプロトタイプしているかについて話し、Draw Something のようなアプリの簡単なプロトタイプをデモしました。彼らは React Native と同様のアプローチを使い、ブリッジを介してネイティブ API へのアクセスを提供しています。これは、アビシェクがデバイスのカメラを使って聴衆の写真を撮り、誰かの頭に帽子を描いたときに実演されました。

NetflixでのReact NativeのためのAPI設計

次に、今夜最初の注目の講演。Netflix のシニアソフトウェアエンジニアであるクラレンス・リョンが、React Native のための API 設計について発表しました。まず、彼が挙げたのは、タブバーや日付ピッカーのようなコンポーネント、カメラロールやアプリ内課金のようなネイティブサービスへのアクセスを提供するライブラリという2種類の主要なライブラリです。React Native で使用するライブラリを構築する際には、2つのアプローチがあります。

  • プラットフォーム固有のコンポーネントを提供する
  • AndroidとiOSの両方で同様のAPIを持つクロスプラットフォームライブラリ

それぞれのアプローチには独自の考慮事項があり、自分のニーズに最も適したものを決定するのはあなた次第です。

アプローチ #1

プラットフォーム固有のコンポーネントの例として、クラレンスはReact NativeコアのDatePickerIOSとDatePickerAndroidについて話しました。iOSでは、日付ピッカーはUIの一部としてレンダリングされ、既存のビューに簡単に組み込むことができますが、Androidではモーダルで表示されます。この場合、個別のコンポーネントを提供するのは理にかなっています。

アプローチ #2

一方、写真ピッカーはAndroidとiOSで同様に扱われます。例えば、AndroidはiOSのようにSelfiesなどのフォルダに写真をグループ化しないなど、わずかな違いはありますが、それらは`if`文と`Platform`コンポーネントを使って簡単に処理できます。

どのようなアプローチを採用するにしても、API の表面積を最小限に抑え、アプリ固有のライブラリを構築するのが良いアイデアです。例えば、iOS のアプリ内課金フレームワークは、一度限りの消費型購入と、更新可能な定期購入をサポートしています。もしあなたのアプリが消費型購入のみをサポートする必要がある場合、クロスプラットフォームライブラリで定期購入のサポートを省略できるかもしれません。

Clarence氏のトークの最後には、短いQ&Aセッションがありました。そこから出てきた興味深い情報の一つは、Netflixでこれらのライブラリのために書かれたReact Nativeコードの約80%が、AndroidとiOSの両方で共有されているということでした。

ギャップを埋める:既存のコードベースで React Native を使用する

今夜の最後の講演は、Airbnb のリーランド・リチャードソンによるものでした。講演は、既存のコードベースで React Native を使用することに焦点を当てていました。私は React Native を使って新しいアプリをゼロから書くのがいかに簡単かを知っていたので、Airbnb が既存のネイティブアプリに React Native を採用した経験を聞くことに非常に興味がありました。

リーランドは、グリーンフィールドアプリとブラウンフィールドアプリについて話すことから始めました。グリーンフィールドとは、以前の作業を考慮せずにプロジェクトを開始することを意味します。これは、既存のプロジェクトの要件、開発プロセス、およびチームのさまざまなニーズを考慮する必要があるブラウンフィールドプロジェクトとは対照的です。

グリーンフィールドアプリに取り組んでいる場合、React Native CLI は Android と iOS の両方に単一のリポジトリを設定し、すべてが機能します。Airbnb で React Native を使用する最初の課題は、Android と iOS アプリがそれぞれ独自のリポジトリを持っていたという事実でした。複数のリポジトリを持つ企業は、React Native を採用する前にいくつかのハードルを乗り越える必要があります。

これを回避するため、AirbnbはまずReact Nativeコードベース用の新しいリポジトリを設定しました。彼らは継続的インテグレーションサーバーを使って、AndroidとiOSのリポジトリをこの新しいリポジトリにミラーリングしました。テストが実行され、バンドルがビルドされた後、ビルド成果物はAndroidとiOSのリポジトリに同期されます。これにより、モバイルエンジニアは開発環境を変更せずにネイティブコードに取り組むことができます。モバイルエンジニアはnpmをインストールしたり、パッカーを実行したり、JavaScriptバンドルをビルドすることを覚えたりする必要はありません。実際のReact Nativeコードを書くエンジニアは、React Nativeリポジトリで直接作業するため、AndroidとiOS間でコードを同期することを心配する必要はありません。

これにはいくつかの欠点がありました。主に、アトミックなアップデートをリリースできなかったことです。ネイティブコードとJavaScriptコードの組み合わせが必要な変更は、3つの別々のプルリクエストが必要となり、すべてを慎重に着陸させる必要がありました。競合を避けるため、ビルド開始後にマスターが変更された場合、CIはAndroidおよびiOSリポジトリへの変更の着陸に失敗します。これにより、コミット頻度の高い日(新しいリリースがカットされる日など)には長い遅延が発生する可能性がありました。

Airbnbはその後、モノレポアプローチに移行しました。幸いなことに、これはすでに検討されており、AndroidとiOSのチームがReact Nativeの使用に慣れると、彼らは喜んでモノレポへの移行を加速させました。

これにより、分割リポジトリのアプローチで抱えていた問題のほとんどが解決されました。Leland氏は、これがバージョン管理サーバーにより高い負荷をかけることになり、小規模な企業にとっては問題になる可能性があると指摘しました。

ナビゲーションの問題

リーランドの講演の後半は、私が心から関心を持っているトピック、つまりReact Nativeにおけるナビゲーション問題に焦点を当てていました。彼は、React Nativeにおける数多くのナビゲーションライブラリについて、ファーストパーティとサードパーティの両方について語りました。NavigationExperimentalは有望に見えたが、彼らのユースケースには適さなかったと述べられました。

実際、既存のナビゲーションライブラリはどれもブラウンフィールドアプリではうまく機能しないようです。ブラウンフィールドアプリでは、ナビゲーションの状態がネイティブアプリによって完全に所有されている必要があります。例えば、React Nativeビューが表示されている間にユーザーのセッションが期限切れになった場合、ネイティブアプリは必要に応じて制御を引き継ぎ、ログイン画面を表示できる必要があります。

Airbnbはまた、移行の一部としてネイティブナビゲーションバーをJavaScriptバージョンに置き換えることを避けたいと考えていました。その影響が不快になる可能性があったからです。当初、彼らはモーダル表示されるビューに限定していましたが、これは明らかにアプリ内でReact Nativeをより広く採用する際に問題を引き起こしました。

彼らは独自のライブラリが必要だと判断しました。そのライブラリは`airbnb-navigation`と呼ばれています。このライブラリはAirbnbのコードベースと強く結びついているため、まだオープンソース化されていませんが、年末までにはリリースしたいと考えています。

ライブラリのAPIについて詳しくは触れませんが、以下にいくつかの重要なポイントを挙げます。

  • シーンを事前に登録する必要がある
  • 各シーンは独自のRCTRootView内に表示されます。これらは各プラットフォームでネイティブに表示されます(例:iOSではUINavigationControllerが使用されます)。
  • シーン内のメインのScrollViewScrollSceneコンポーネントでラップする必要があります。そうすることで、iOSでステータスバーをタップして一番上にスクロールするなどのネイティブの動作を活用できます。
  • シーン間のトランジションはネイティブで処理されるため、パフォーマンスについて心配する必要はありません。
  • Androidのバックボタンは自動的にサポートされます。
  • Navigator.ConfigというUIレスコンポーネントを介して、View Controllerベースのナビゲーションバーのスタイリングを活用できます。

また、留意すべきいくつかの考慮事項もあります。

  • ナビゲーションバーはネイティブコンポーネントであるため、JavaScriptで簡単にカスタマイズすることはできません。これは意図的なもので、ネイティブのナビゲーションバーを使用することがこのタイプのライブラリの厳しい要件だからです。
  • ScreenPropsはブリッジを介して送信されるたびにシリアライズ/デシリアライズする必要があるため、ここで大量のデータを送信する際には注意が必要です。
  • ナビゲーションの状態はネイティブアプリによって所有されているため(これもライブラリの厳しい要件)、Reduxのようなものでナビゲーションの状態を操作することはできません。

リーランドの講演の後にはQ&Aセッションも行われました。全体的に、AirbnbはReact Nativeに満足しています。彼らはApp Storeを介さずに問題を修正するためにCode Pushを使用することに興味を持っており、彼らのエンジニアはLive Reloadを気に入っています。なぜなら、彼らは少しの変更ごとにネイティブアプリが再構築されるのを待つ必要がないからです。

閉会の辞

イベントは、いくつかの追加のReact Nativeニュースで締めくくられました。

ミートアップは、コミュニティの他の開発者と出会い、学ぶ良い機会を提供します。今後もさらに多くの React Native ミートアップに参加することを楽しみにしています。もしこれらのどれかに参加されるなら、ぜひ私を見つけて、React Native をあなたにとってより良くするためにどうすればよいか教えてください!

より良いドキュメンテーションに向けて

·5分で読めます
Kevin Lacker
Facebook エンジニアリングマネージャー

優れた開発者体験には、優れたドキュメントが不可欠です。優れたドキュメントを作成するには多くの努力が必要で、理想的なドキュメントは簡潔で、役立ち、正確で、完全で、そして楽しいものです。最近、私たちは皆さんのフィードバックに基づいてドキュメントを改善するために懸命に作業しており、これまでに改善した点の一部を共有したいと思います。

インラインの例

新しいライブラリ、新しいプログラミング言語、または新しいフレームワークを学ぶとき、初めてコードを書き、試してみて、それが機能するかどうかを確認する美しい瞬間があります...そしてそれは_本当に_機能します。あなたは何か現実のものを創造しました。私たちはその直感的な体験をドキュメントに直接組み込みたいと考えました。このように

import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';

class ScratchPad extends Component {
render() {
return (
<View style={{flex: 1}}>
<Text style={{fontSize: 30, flex: 1, textAlign: 'center'}}>
Isn't this cool?
</Text>
<Text style={{fontSize: 100, flex: 1, textAlign: 'center'}}>
👍
</Text>
</View>
);
}
}

AppRegistry.registerComponent('ScratchPad', () => ScratchPad);

`react-native-web-player`モジュールとDevin Abbottの助けを借りて実現した、これらのインライン例は、React Nativeの基礎を学ぶ素晴らしい方法であると考えており、新しいReact Native開発者向けのチュートリアルを可能な限りこれらの例を使用するように更新しました。ぜひ試してみてください。もしサンプルコードを少しだけ変更したらどうなるか興味を持ったことがあるなら、これは本当に素晴らしい方法です。また、開発者ツールを構築していて、自分のサイトにライブのReact Nativeサンプルを表示したい場合、`react-native-web-player`を使えば簡単に行えます。

コアとなるシミュレーションエンジンは、Nicolas Gallagher`react-native-web`プロジェクトによって提供されており、これは`Text`や`View`のようなReact Nativeコンポーネントをウェブ上で表示する方法を提供します。もしコードベースの大部分を共有するモバイルとウェブ体験を構築することに興味があるなら、`react-native-web`をチェックしてみてください。

より良いガイド

React Nativeの一部の機能には複数の実現方法があり、より良いガイダンスを提供すべきだというフィードバックをいただきました。

異なるアプローチを比較し、`Navigator`、`NavigatorIOS`、`NavigationExperimental`のどれを使用すべきかをアドバイスする新しいナビゲーションガイドを作成しました。中期的には、これらのインターフェースの改善と統合に取り組んでいます。短期的には、より良いガイドが皆さんの生活を楽にすることを願っています。

ボタンのようなインターフェースを作成する基本的な方法と、タッチイベントを処理するさまざまな方法を簡潔にまとめた、タッチ処理に関する新しいガイドも作成しました。

私たちが取り組んだもう一つの分野はFlexboxです。これには、Flexboxでレイアウトを処理する方法コンポーネントのサイズを制御する方法に関するチュートリアルが含まれます。また、目立たないかもしれませんが、役立つと思われるReact Nativeでレイアウトを制御するすべてのプロパティのリストも含まれています。

はじめに

マシンに React Native 開発環境をセットアップし始める際には、多くのインストールと設定を行う必要があります。インストールを本当に楽しくてエキサイティングな体験にすることは難しいですが、少なくともできる限り迅速で苦痛の少ないものにすることはできます。

私たちは、開発OSとモバイルOSを事前に選択できる新しい入門ワークフローを構築し、すべての設定手順を簡潔にまとめた場所を提供しました。また、インストールプロセス全体を確認し、すべての決定ポイントに明確な推奨事項があることを確認しました。無邪気な同僚たちに試してもらった結果、これは改善であると確信しています。

また、既存のアプリにReact Nativeを統合するためのガイドにも取り組みました。Facebookアプリ自体のようなReact Nativeを使用している大規模なアプリの多くは、実際にはアプリの一部をReact Nativeで構築し、残りの部分を通常の開発ツールを使用して構築しています。このガイドが、より多くの人々がこの方法でアプリを構築するのを容易にすることを願っています。

皆様の助けが必要です

あなたのフィードバックは、私たちが何を優先すべきかを教えてくれます。このブログ記事を読んで「より良いドキュメント?ふざけるな。Xのドキュメントはまだゴミだ!」と思う人もいるでしょう。それは素晴らしいことです。そのエネルギーが必要です。私たちにフィードバックを与える最善の方法は、フィードバックの種類によって異なります。

ドキュメントに間違いがある場合(不正確な説明や動作しないコードなど)は、Issue を提出してください。「Documentation」というタグを付けてください。そうすれば、適切な担当者に割り当てやすくなります。

具体的な間違いはないが、ドキュメントの何かが根本的に分かりにくい場合は、GitHub の Issue にはあまり適していません。代わりに、Canny に、改善が必要なドキュメントの分野について投稿してください。これは、ガイドの執筆のようなより一般的な作業を行う際に、私たちが優先順位を決定するのに役立ちます。

ここまで読んでいただき、React Nativeをご利用いただきありがとうございます!

React Native: 1年のレビュー

·2分で読めます
Martin Konicek
Facebook ソフトウェアエンジニア

React Native をオープンソース化してから1年が経ちました。数人のエンジニアによるアイデアから始まったものは、今や Facebook をはじめとするプロダクトチームで使われるフレームワークとなっています。本日 F8 で、Microsoft が React Native を Windows エコシステムに導入すると発表しました。これにより、開発者は Windows PC、Phone、Xbox で React Native を構築する可能性を得ます。また、Visual Studio Code 用の React Native 拡張機能や CodePush などのオープンソースツールとサービスを提供し、開発者が Windows プラットフォームで React Native アプリを作成するのを支援します。さらに、Samsung は、数百万台のスマートテレビ、モバイル、ウェアラブルデバイス向けアプリを開発できるハイブリッドプラットフォーム向けに React Native を構築しています。また、開発者がログイン、共有、アプリ分析、Graph API などの Facebook ソーシャル機能をアプリに簡単に組み込める React Native 用 Facebook SDK もリリースしました。1年間で、React Native は主要なすべてのプラットフォームでの開発方法を変えました。

これは壮大な道のりでしたが、まだ始まったばかりです。React Nativeが1年前にオープンソース化されてからどのように成長し、進化してきたか、その過程で直面したいくつかの課題、そして未来に目を向ける中で私たちが期待していることを振り返ります。

これは抜粋です。記事の全文はFacebook Codeでご覧ください。

React Nativeのパフォーマンスを深く掘り下げる

·2分で読めます
Pieter De Baets
Facebook ソフトウェアエンジニア

React Native を使うと、React と Relay の宣言的プログラミングモデルを使用して、JavaScript で Android および iOS アプリを構築できます。これにより、より簡潔で理解しやすいコード、コンパイルサイクルなしでの高速なイテレーション、複数のプラットフォーム間でのコードの簡単な共有が可能になります。より迅速にリリースでき、本当に重要な詳細に集中して、アプリを素晴らしく見せ、感じさせることができます。パフォーマンスの最適化は、その大きな部分を占めます。ここでは、React Native アプリの起動速度を2倍にする方法について説明します。

なぜ急ぐのか?

アプリの動作が速くなると、コンテンツの読み込みが速くなり、人々がコンテンツを操作する時間が増え、スムーズなアニメーションがアプリの利用を楽しくします。新興市場では、2011年クラスの電話2Gネットワーク上で主流を占めるため、パフォーマンスに注力することが、アプリが使用可能かどうかを左右する可能性があります。

iOSAndroid向けにReact Nativeをリリースして以来、リストビューのスクロール性能、メモリ効率、UIの応答性、そしてアプリの起動時間を改善してきました。起動はアプリの第一印象を決定し、フレームワークのすべての部分に負荷をかけるため、最もやりがいがあり、かつ困難な問題です。

これは抜粋です。記事の全文はFacebook Codeでお読みください。

ホットリローディングの導入

·9分で読めます
Martín Bigio
Instagram ソフトウェアエンジニア

React Nativeの目標は、可能な限り最高の開発者体験を提供することです。その大部分を占めるのが、ファイルを保存してから変更を確認できるまでの時間です。私たちの目標は、アプリが成長してもこのフィードバックループを1秒未満にすることです。

私たちは3つの主要な機能を通じてこの理想に近づきました。

  • 言語としてJavaScriptを使用することで、長いコンパイルサイクルタイムがなくなります。
  • Packagerと呼ばれるツールを実装しました。これはes6/flow/jsxファイルを、VMが理解できる通常のJavaScriptに変換します。これはサーバーとして設計されており、中間状態をメモリに保持することで高速な差分変更を可能にし、複数のコアを使用します。
  • 保存時にアプリをリロードするLive Reloadという機能を構築しました。

この時点で、開発者にとってのボトルネックは、アプリをリロードするのにかかる時間ではなく、アプリの状態を失うことです。一般的なシナリオは、起動画面から複数の画面離れた機能に取り組むことです。リロードするたびに、同じパスを何度もクリックして機能に戻る必要があり、サイクルが数秒長くなります。

ホットリロード

ホットリロードの背後にある考え方は、アプリを実行し続け、編集したファイルの新しいバージョンを実行時に注入することです。これにより、アプリの状態が失われず、特にUIを微調整している場合に便利です。

動画は百聞に一見に如かずです。Live Reload(現在)とHot Reload(新規)の違いをご覧ください。

よく見ると、レッドボックスから回復できること、また、以前は存在しなかったモジュールをフルリロードなしでインポートし始めることができることにお気づきでしょう。

警告: JavaScriptは非常に状態を持つ言語であるため、ホットリロードを完全に実装することはできません。実際には、現在のセットアップは多くの一般的なユースケースでうまく機能しており、何かがうまくいかなくなった場合は常に完全なリロードが可能です。

ホットリロードは0.22から利用可能です。有効にするには

  • 開発者メニューを開きます
  • 「Enable Hot Reloading」をタップします

実装の概要

なぜそれが必要で、どのように使用するのかを見てきましたが、ここからが楽しい部分です:実際にどのように機能するのか。

ホットリローディングは、ホットモジュール置換(HMR)という機能の上に構築されています。これはwebpackによって最初に導入され、React Native Packagerの内部に実装されました。HMRはPackagerにファイル変更を監視させ、薄いHMRランタイムにHMR更新を送信します。

要するに、HMRアップデートには変更されたJSモジュールの新しいコードが含まれています。ランタイムがそれらを受け取ると、古いモジュールのコードを新しいものに置き換えます。

HMR アップデートには、変更したいモジュールのコードだけでなく、もう少し多くの情報が含まれています。なぜなら、それを置き換えるだけでは、ランタイムが変更を認識するのに十分ではないからです。問題は、モジュールシステムがすでに更新したいモジュールの_エクスポート_をキャッシュしている可能性があることです。例えば、次のような2つのモジュールで構成されるアプリがあるとします。

// log.js
function log(message) {
const time = require('./time');
console.log(`[${time()}] ${message}`);
}

module.exports = log;
// time.js
function time() {
return new Date().getTime();
}

module.exports = time;

モジュールlogは、モジュールtimeから提供される現在の日付を含んだメッセージを出力します。

アプリがバンドルされると、React Nativeは各モジュールを__d関数を使用してモジュールシステムに登録します。このアプリでは、多くの__d定義の中にlogのためのものがあります。

__d('log', function() {
... // module's code
});

この呼び出しは、各モジュールのコードを匿名関数でラップします。これを一般的にファクトリ関数と呼びます。モジュールシステムランタイムは、各モジュールのファクトリ関数、それがすでに実行されたかどうか、およびその実行結果(エクスポート)を追跡します。モジュールが要求されると、モジュールシステムはすでにキャッシュされているエクスポートを提供するか、モジュールのファクトリ関数を初めて実行して結果を保存します。

アプリを起動し、`log` を要求するとします。この時点では、`log` も `time` のファクトリ関数も実行されていないため、エクスポートはキャッシュされていません。その後、ユーザーが `time` を `MM/DD` で日付を返すように変更します。

// time.js
function bar() {
const date = new Date();
return `${date.getMonth() + 1}/${date.getDate()}`;
}

module.exports = bar;

Packagerはtimeの新しいコードをランタイムに送信し(ステップ1)、最終的にlogがrequireされると、エクスポートされた関数が実行され、timeの変更が反映されます(ステップ2)。

次に、logのコードがトップレベルのrequireとしてtimeを必要とするとします。

const time = require('./time'); // top level require

// log.js
function log(message) {
console.log(`[${time()}] ${message}`);
}

module.exports = log;

`log` が必要とされたとき、ランタイムはそのエクスポートと `time` のエクスポートをキャッシュします (ステップ 1)。次に、`time` が変更されたとき、HMR プロセスは `time` のコードを置き換えただけで単純に終了することはできません。もしそうした場合、`log` が実行されたときに、`time` のキャッシュされたコピー (古いコード) で実行されてしまいます。

`log` が `time` の変更を認識するためには、依存するモジュールの1つがホットスワップされたため、キャッシュされたエクスポートをクリアする必要があります (ステップ 3)。最後に、`log` が再度要求されたとき、そのファクトリ関数が実行され、`time` を要求して新しいコードを取得します。

HMR API

React Native の HMR は、`hot` オブジェクトを導入することでモジュールシステムを拡張します。この API は webpack のものに基づいています。`hot` オブジェクトは `accept` という関数を公開しており、モジュールがホットスワップされる必要があるときに実行されるコールバックを定義できます。例えば、`time` のコードを次のように変更すると、`time` を保存するたびにコンソールに「time changed」と表示されます。

// time.js
function time() {
... // new code
}

module.hot.accept(() => {
console.log('time changed');
});

module.exports = time;

このAPIを手動で使用する必要があるのはまれなケースのみであることに注意してください。ホットリロードは、最も一般的なユースケースではそのまま機能するはずです。

HMRランタイム

以前に見たように、HMR 更新を受け入れるだけでは不十分な場合があります。なぜなら、ホットスワップされているモジュールを使用するモジュールがすでに実行され、そのインポートがキャッシュされている可能性があるからです。例えば、映画アプリの依存関係ツリーが、前の例の `log` および `time` モジュールに依存するトップレベルの `MovieRouter` が `MovieSearch` および `MovieScreen` ビューに依存しているとします。

ユーザーが映画の検索ビューにアクセスしたが、別のビューにはアクセスしなかった場合、`MovieScreen` を除くすべてのモジュールはエクスポートをキャッシュしています。`time` モジュールに変更が加えられた場合、ランタイムは `log` のエクスポートをクリアして、`time` の変更を認識させる必要があります。プロセスはそこで終わりません。ランタイムは、すべての親が受け入れられるまでこのプロセスを再帰的に繰り返します。そのため、`log` に依存するモジュールを取得し、それらを受け入れようとします。`MovieScreen` の場合は、まだ必要とされていないため、中止できます。`MovieSearch` の場合は、そのエクスポートをクリアし、親を再帰的に処理する必要があります。最後に、`MovieRouter` に対して同じことを行い、それに依存するモジュールがないため、そこで終了します。

依存関係ツリーをたどるために、ランタイムはHMRアップデートでPackagerから逆依存関係ツリーを受け取ります。この例では、ランタイムは次のようなJSONオブジェクトを受け取ります。

{
modules: [
{
name: 'time',
code: /* time's new code */
}
],
inverseDependencies: {
MovieRouter: [],
MovieScreen: ['MovieRouter'],
MovieSearch: ['MovieRouter'],
log: ['MovieScreen', 'MovieSearch'],
time: ['log'],
}
}

Reactコンポーネント

React コンポーネントをホットリローディングで動作させるのは少し難しいです。問題は、古いコードを新しいコードに単純に置き換えるだけでは、コンポーネントの状態が失われてしまうことです。React Web アプリケーションの場合、Dan Abramov は、この問題を解決するために Webpack の HMR API を使用する Babel トランスフォームを実装しました。簡単に言えば、彼のソリューションは、_トランスフォーム時_にすべての React コンポーネントのプロキシを作成することで機能します。プロキシはコンポーネントの状態を保持し、ライフサイクルメソッドを実際のコンポーネントに委譲します。これがホットリロードされるものです。

プロキシコンポーネントを作成するだけでなく、このtransformはReactにコンポーネントの再レンダリングを強制するコードでaccept関数も定義します。これにより、アプリの状態を失うことなくレンダリングコードをホットリロードできます。

React Native に付属のデフォルトのトランスフォーマーは、`babel-preset-react-native` を使用しており、これは webpack を使用する React Web プロジェクトで `react-transform` を使用するのと同じ方法で設定されています。

Reduxストア

Reduxストアでホットリロードを有効にするには、webpackを使用するWebプロジェクトで行うのと同様にHMR APIを使用するだけです。

// configureStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../reducers';

export default function configureStore(initialState) {
const store = createStore(
reducer,
initialState,
applyMiddleware(thunk),
);

if (module.hot) {
module.hot.accept(() => {
const nextRootReducer = require('../reducers/index').default;
store.replaceReducer(nextRootReducer);
});
}

return store;
};

リデューサーを変更すると、そのリデューサーを受け入れるコードがクライアントに送信されます。すると、クライアントはリデューサーが自分自身を受け入れる方法を知らないことに気づき、参照しているすべてのモジュールを探してそれらを受け入れようとします。最終的に、フローは単一のストア、つまり`configureStore`モジュールに到達し、HMR更新を受け入れます。

結論

ホットリロードの改善に協力することに興味がある方は、Dan Abramov のホットリロードの将来に関する投稿を読み、貢献することをお勧めします。例えば、Johny Days は複数の接続されたクライアントで動作するようにする予定です。私たちは皆さんのこの機能の維持と改善を期待しています。

React Nativeを使えば、アプリの構築方法を再考し、素晴らしい開発者体験を実現する機会があります。ホットリロードはパズルのピースの一つにすぎません。それをより良くするために、他にどんなクレイジーなハックができるでしょうか?

React Nativeアプリをアクセシブルにする

·2分で読めます
Georgiy Kassabli
Facebook ソフトウェアエンジニア

ウェブでのReactの最近のリリースとモバイルでのReact Nativeのリリースにより、私たちは開発者向けに製品を構築するための新しいフロントエンドフレームワークを提供しました。堅牢な製品を構築する上で重要な側面の一つは、視覚障害やその他の障害を持つ人々を含む、誰もがそれを使用できるようにすることです。ReactとReact NativeのアクセシビリティAPIは、盲人や視覚障害者向けのスクリーンリーダーのような支援技術を使用する人でも、Reactで動くあらゆる体験を利用できるようにします。

この記事では、React Native アプリケーションに焦点を当てます。React Accessibility API は、Android および iOS API と同様の外観と操作感を持つように設計されています。以前に Android、iOS、または Web 向けにアクセシブルなアプリケーションを開発したことがある方なら、React AX API のフレームワークと用語に慣れていることでしょう。例えば、UI 要素を_アクセシブル_に設定(したがって、支援技術に公開)し、_accessibilityLabel_ を使用して要素の文字列説明を提供することができます。

<View accessible={true} accessibilityLabel=”This is simple view”>

Facebook自身のReact製プロダクトの一つである広告マネージャアプリを例に、React AX APIのもう少し踏み込んだ応用を見ていきましょう。

これは抜粋です。記事の全文はFacebook Codeでご覧いただけます。

React Native for Android: 最初のクロスプラットフォームReact Nativeアプリをどのように構築したか

·2分で読めます
Facebook ソフトウェアエンジニア

今年の初めに、私たちはiOS向けReact Nativeを導入しました。React Nativeは、WebのReactで開発者が慣れ親しんだ宣言型の自己完結型UIコンポーネントと高速な開発サイクルをモバイルプラットフォームにもたらしつつ、ネイティブアプリケーションの速度、忠実度、感覚を保持します。本日、私たちはAndroid向けReact Nativeをリリースできることを嬉しく思います。

Facebookでは、React Nativeを本番環境で1年以上使用しています。ちょうど1年前、私たちのチームは広告マネージャーアプリの開発に着手しました。私たちの目標は、Facebookで広告を出す数百万人の人々が外出先でアカウントを管理し、新しい広告を作成できる新しいアプリを作成することでした。結果として、それはFacebook初の完全なReact Nativeアプリであるだけでなく、初のクロスプラットフォームアプリでもありました。この記事では、このアプリをどのように構築したか、React Nativeがどのようにして開発を加速させたか、そして私たちが学んだ教訓を皆さんと共有したいと思います。

これは抜粋です。残りの記事は Facebook Code でお読みください。

React Native: モダンなウェブ技術をモバイルへ

·3分で読めます
Tom Occhino
Facebook エンジニアリングマネージャー

私たちは2年前にReactを世に紹介しましたが、それ以来、Facebook内外で目覚ましい成長を遂げています。現在、強制ではないにもかかわらず、Facebookの新しいWebプロジェクトは一般的に何らかの形でReactを使用して構築されており、業界全体で広く採用されています。エンジニアは、フレームワークとの戦いに費やす時間を減らし、製品に集中する時間を増やすことができるため、毎日Reactを使用することを選択しています。しかし、Reactでしばらく構築してから、その強力さを理解し始めました。

React は、アプリケーションを個別のコンポーネントに分解することを強制します。各コンポーネントは単一のビューを表します。これらのコンポーネントにより、製品を簡単に反復処理できます。なぜなら、システム全体を頭に留めておく必要なく、その一部を変更できるからです。しかし、さらに重要なのは、React が DOM の可変で命令的な API を宣言的な API でラップすることで、抽象化のレベルを上げ、プログラミングモデルを簡素化していることです。私たちが発見したのは、React で構築すると、コードがはるかに予測可能になるということです。この予測可能性により、自信を持ってより迅速に反復処理でき、その結果、アプリケーションははるかに信頼性の高いものになります。さらに、React で構築されたアプリケーションをスケーリングするだけでなく、チーム自体の規模をスケーリングすることも容易になりました。

Web の迅速なイテレーションサイクルと相まって、Facebook.com の多くのコンポーネントを含む、素晴らしい製品を React で構築することができました。さらに、Relay のように、React の上に JavaScript で素晴らしいフレームワークを構築しました。これにより、大規模なデータフェッチを大幅に簡素化できます。もちろん、Web は話の一部にすぎません。Facebook には、切断された独自のテクノロジースタックの上に構築された、広く使用されている Android および iOS アプリもあります。複数のプラットフォームの上にアプリを構築しなければならないことは、当社のエンジニアリング組織を二分しましたが、これはネイティブモバイルアプリケーション開発を困難にするものの1つにすぎません。

これは抜粋です。残りの記事はFacebook Codeでお読みください。