React

React (リアクト) は、Meta（旧Facebook）とコミュニティによって開発されているユーザインタフェース構築のためのJavaScriptライブラリである。React.jsまたはReactJSの名称でも知られている。 Reactはシングルページアプリケーションやモバイルアプリケーションの開発におけるベースとして使用することができる。複雑なReactアプリケーションでは通常、状態管理・ルーティング・APIとの対話のための追加のライブラリが必要となる。 ReactはFacebookのソフトウェアエンジニアであるJordan Walkeによって開発された。PHP向けのHTMLコンポーネントフレームワークであるXHP（英語版）の影響を受けている。2011年にFacebookのニュースフィード上で最初に使用され、2012年にはInstagramでも使用されるようになった。2013年5月のJSConf USでオープンソース化された。 React NativeはAndroid・iOS・UWPでのReactを利用したネイティブ開発を可能にするもので、2015年2月のReact.js Confで発表され、3月にオープンソース化された。 2017年4月17日、Facebookはユーザインタフェースを構築するためのReactフレームワークライブラリの新しいコアアルゴリズムであるReact Fiber（英語版）を発表した。React FiberはReactフレームワークの将来の改良と機能開発の基盤となるものである。 以下はJSXとJavaScriptを利用したReactの基本的な使い方である。 <!DOCTYPE html> <html> <head> <title>Example</title> </head> <body> <div id="root"></div> </body> </html> import React from "react"; import ReactDOM from "react-dom/client"; const Greeter = (props) => { return ( <h1>{props.greeting}</h1> ); }; const App = () => { return <Greeter greeting="Hello, world!" />; }; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <App /> </React.StrictMode> ); Reactが提供する代表的な機能を以下に挙げる。 宣言的UI（テンプレーティング）: JSX データバインディング コンポーネント化: 関数コンポーネント 高効率レンダリング: 仮想DOM プロパティ (通常はprops) は親コンポーネントからコンポーネントに渡される。コンポーネントは1組のイミュータブルなJavaScriptオブジェクトとしてプロパティを受け取る。 stateはコンポーネントの全体に渡って値を保持し、プロパティを通じて子コンポーネントに渡すことができる。 class ParentComponent extends React.Component { state = { color: "green" }; render() { return <ChildComponent color={this.state.color} />; } } もう1つの注目すべき機能は、仮想DOMの使用である。Reactでは仮想DOMとしてメモリ上にDOMの状態をキャッシュしておき、仮想DOMに差分が発生した場合にのみ差分を計算し、実際のDOMに差分のみを反映させることにより効率的な描画を実現している。これにより、プログラマは変更があるたびにページ全体を描画するコードを記述しながら、Reactライブラリによって実際に変更されたサブコンポーネントのみを描画することができる。 ライフサイクルメソッドはコンポーネントの生存期間中に設定した地点で、コードを実行できるようにするためのフックである。 shouldComponentUpdate - 描画が不要な場合にfalseを返すことによって、コンポーネントの不要な再描画を防ぐことができる。 componentDidMount - コンポーネントがマウントされるときに1回だけ呼び出される。これは一般に、APIを介してリモートソースからデータを読み込む際のトリガとして使用されている。 render - 最も重要なライフサイクルメソッドであり、どのコンポーネントでも必要な唯一のものである。このメソッドは、通常はユーザインタフェースの変更を反映して、コンポーネントの状態が更新されるたびに呼び出される。 JSX（英語版）は、JavaScriptの構文に対する拡張である。HTMLと外観が似ているが、JSXは多くの開発者がよく知っている構文を使用して、構造化されたコンポーネントを描画する方法を提供する。Reactコンポーネントは、必須ではないが、通常はJSXを使用して書かれている。JSXはFacebookがPHP向けに作成した拡張構文であるXHPに似ている。 JSXのコードの例: const App = () => { return ( <div> <p>Header</p> <p>Content</p> <p>Footer</p> </div> ); }; 入れ子の要素 同じレベルの複数の要素は、上記の<div>のように単一のコンテナ要素にラップするか、配列として返す必要がある。 属性 JSXはHTMLによって提供されるものを反映するように設計された要素属性の範囲を提供する。カスタム属性もコンポーネントに渡すことができる。全ての属性はコンポーネントによってpropsとして受け取られる。 JavaScriptの式 JavaScriptの式 (文ではない) は、{}を使うことによってJSXのコード内に記述することができる。 <h1>{10 + 1}</h1>; 上記のコードは下記のように描画される。 <h1>11</h1> 条件文 if文はJSX内で使用することはできないが、条件式は使用することができる。以下の例では、i === 1が評価され、「true」または「false」の文字列が描画される。 const App = ({ i }) => { return <div>{i === 1}</div>; }; 関数とJSXは条件式内で使用することができる。 const App = () => { const sections = [1, 2, 3]; return ( <div> {sections.map((n) => ( <div>Section {n}</div> ))} </div> ); }; 上記は下記のように描画される。 <div> <div>Section 1</div> <div>Section 2</div> <div>Section 3</div> </div> JSXで書かれたコードはウェブブラウザで実行可能にするために、Babelなどのツールを利用して事前に変換する必要がある。この処理は通常はアプリケーションが配置されるよりも前の、ソフトウェアを構築している段階で実行される。 Reactは「レンダラーに依存しないこと」を設計原則としている。ゆえにReactはウェブブラウザでHTMLを描画すること（DOMによるレンダリング）以外にも適用される。例えば、Facebookはcanvasタグに描画する動的チャートを持ち、NetflixとPayPalではサーバとクライアントの両方で読み込むことができる同一のHTMLを描画するために利用されている。またReact NativeによりネイティブアプリのUIレイヤーとしても機能する。 Reactは完全なアプリケーションフレームワークを提供しようとはしていない。Reactはユーザインタフェースを構築するために設計されており、故に、開発者がアプリケーションを構築する際に必要であると考えるかもしれない多くのツールは含まれていない。このことにより、開発者はネットワークアクセスやローカルデータストレージなどで好みのライブラリを選択することができる。ライブラリが成熟するにつれて、一般的なパターンが明らかになってきた。 Fluxアーキテクチャは、AngularJSの双方向データフローとは対照的なReactの単方向データフローの概念をサポートするために、一般的なMVCアーキテクチャの代替となるものである。FluxはActionが中央Dispatcherを介してStoreに送信され、Storeに対する変更がViewに伝播することが特徴である。Reactと共に使用した場合には、この伝播はコンポーネントのプロパティを通じて行われる。 Fluxはオブザーバ・パターンの変種であると考えることができる。 Fluxアーキテクチャの下でのReactコンポーネントは、渡されたpropsを直接変更するのではなく、Storeを変更するためにDispatcherによって送信されるActionを作成するコールバック関数に渡されるべきである。Actionは何が起こったのかを説明する義務のあるオブジェクトである。例えば、あるユーザーが別のユーザーをフォローすると記述されたActionには、自身のユーザーIDと相手のユーザーIDとUSER_FOLLOWED_ANOTHER_USERが含まれている。StoreはDispatcherから受け取ったActionに応じて自身を変更する可能性がある。 このパターンは、「プロパティが下に流れ、アクションが上に流れる」と表現されることがある。多くのFluxの実装がこのアーキテクチャの誕生以来作られてきたが、恐らく最もよく知られている実装は単一のStoreを特徴とするReduxであり、しばしば信頼できる唯一の情報源と呼ばれている。 React NativeはFacebookによって2015年2月に発表され、ネイティブのAndroid・iOS・UWPにReactを適用した。 2012年、Facebookの会長兼CEOであるマーク・ザッカーバーグは、「企業としての最大の失敗は、ネイティブの反対としてHTML5に大きく賭けたことだった。」とコメントしている。彼はFacebookがまもなくより良いモバイル体験を提供することを約束した。 Facebookの社内では、Jordan WalkeがバックグラウンドのJavaScriptのスレッドからiOSのUI要素生成する方法を発見した。彼らはこの技術を使ってネイティブアプリを構築することができるように、このプロトタイプを完成させるため社内ハッカソンを結成することにした。 数ヶ月の開発の後、FacebookはReact.js Conf 2015で最初のバージョンをリリースした。Christopher Chedeauは技術的な話の中で、FacebookがReact Nativeをグループアプリと彼らの広告管理アプリで既に使用していると説明した。 React Nativeの動作原理は基本的にはReactと同一だが、ネイティブAPIを利用して描画する点がReactと異なる。React Nativeはバックグラウンドプロセス (開発者の書いたコードを解釈するためのJavaScript処理系) としてエンドデバイス上で直接実行され、シリアライズ可能で非同期（英語版）かつバッチ処理されたBridgeを介してネイティブプラットフォームと通信する。 React NativeはHTML5に全く頼らず、全てJavaScriptで書かれており、ネイティブのSDKに頼っている。 React NativeによるHello world: import React from "react"; import { AppRegistry, Text } from "react-native"; export const HelloWorldApp = () => <Text>Hello world!</Text>; AppRegistry.registerComponent("HelloWorld", () => HelloWorldApp); プロジェクトの進捗状況は、コア開発チームのディスカッションフォーラムで見ることができる。しかし、Reactに対する大きな変更についてはreact-futureリポジトリのIssueとプルリクエストを通すことになっている。これによって、Reactコミュニティは将来性のある新しい機能・実験的なAPI・JavaScriptの構文の改善についてのフィードバックを提供することができる。 サブプロジェクトの状態についてはプロジェクトのwikiで利用可能だった。 FacebookはReactの貢献者に対して、Facebookの貢献者ライセンス同意書（英語版） (CLA) に署名することを要求している。 Reactに対する批判として、仮想DOMの概念を使用しているため、多くのRAMが必要になるというものがある。これは、「UIの表現がメモリ上に保持され、ReactDOMなどのライブラリによって実際のDOMと同期される」ことによるものである。同様に、React バージョン16以降に含まれている仮想DOMの抽象化は、ウェブブラウザに組み込まれているコンポーネントモデルでは上手く動作せず、従って、ウェブブラウザの標準に依存したそれらのコンポーネントを実装する代替ライブラリでは上手く機能しない。 2013年5月に最初に一般公開されたときには標準のApache 2.0を使用していた。2014年10月に公開されたReact バージョン0.12.0からは、Facebookの関連する特許の使用を認めるPATENTSテキストファイルが追加された、特許条項の付きの修正BSDライセンスにライセンスを変更した。 "The license granted hereunder will terminate, automatically and without notice, for anyone that makes any claim (including by filing any lawsuit, assertion or other action) alleging (a) direct, indirect, or contributory infringement or inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or affiliates, whether or not such claim is related to the Software, (ii) by any party if such claim arises in whole or in part from any software, product or service of Facebook or any of its subsidiaries or affiliates, whether or not such claim is related to the Software, or (iii) by any party relating to the Software; or (b) that any right in any patent claim of Facebook is invalid or unenforceable." この特許条項はFacebookとその関連企業に対して特許権侵害訴訟した場合に、利用する権利が取り消されるというもので、Reactユーザーコミュニティ内で幾つかの論争と議論を引き起こした。 コミュニティからのフィードバックに基づき、2015年4月にFacebookは特許許諾を曖昧な部分を減らし、より寛容なものになるように変更した。 "The license granted hereunder will terminate, automatically and without notice, if you (or any of your subsidiaries, corporate affiliates or agents) initiate directly or indirectly, or take a direct financial interest in, any Patent Assertion: (i) against Facebook or any of its subsidiaries or corporate affiliates, (ii) against any party if such Patent Assertion arises in whole or in part from any software, technology, product or service of Facebook or any of its subsidiaries or corporate affiliates, or (iii) against any party relating to the Software. [...] A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, or contributory infringement or inducement to infringe any patent, including a cross-claim or counterclaim." 2017年8月、Apacheソフトウェア財団はこの特許条項がApacheの製品と相容れないものであったことからライセンスの変更を求めたが、Facebookはこれを却下した。翌月、WordPressはGutenbergとCalypsoでReactの利用を中止することを決定した。 2017年9月23日、Facebookは翌週に、Flow・Jest・React・Immutable.jsの4つを標準のMITライセンスで再ライセンスすることを発表した。同社は、Reactが「ウェブ用のオープンソースソフトウェアにおける様々なエコシステムの基盤」であり、「技術的なもの以外の問題によって発展を遅らせることは望まない」と述べている。 同月26日に、React バージョン16.0.0が標準のMITライセンスでリリースされた。この変更はReact バージョン15.6.2でバージョン15.x系にもバックポートされた。