React

**React** (リアクト)または**React.js**、**ReactJS** とは、ウェブブラウザで複雑なUIを容易に生成するためのフリーかつオープンソースなフロントエンドJavaScriptライブラリである。Meta（旧Facebook）が2011年から社内用に開発していたライブラリを2013年に一般に公開したもので、Meta社と個人や企業からなるコミュニティによって開発されている。

## 概要
Reactの主な特徴は、クライアントサイドであること、コンポーネントベースであること、仮想DOMを扱うことである。

Reactはクライアントサイドである。従来、データファイルや通信内容をもとに複雑なUIをもったWebページ用HTMLを生成するためには、PHPやJava、RubyなどWEBサーバー上で動くサーバーサイド言語が用いられていた。それに対して、Reactはブラウザ上で動くJavaScriptを使い、ページ表示後にHTMLタグ要素を既存のHTMLに挿入するJSXとよばれる手法によりクライアントサイドで動作するという特徴がある（ただし後に登場したRSC(React Server Components)機能でサーバーサイドレンダリングも可能）。

Reactはコンポーネントベースである。先行するクライアントサイドのUI開発に使われていたjQuery等と比べ、コンポーネントを単位にした要素ごとの開発が可能であり、大規模な開発に適している。

Reactは仮想DOMを採用し、軽量に更新可能である。仮想DOMとは、HTML言語の階層木構造(DOM)を直接操作するのではなく、仮想的なDOMを操作し最小限の変更点のみ実際のDOMに反映する機能で、Vue.jsなども採用している。

Reactは単独でも動作するが、予約サイトなど双方向の通信機能によって表示を変える動的ページの構築では、サーバーサイドの処理をNode.js(JavaScriptのサーバーサイド向け拡張)と組み合わせたりNext.js(Node.jsのライブラリ)と組み合わせて使われることが一般的である。また、Reactの実際の開発では、直接JavaScriptを書くのではなく、TypeScript(JavaScriptを型付きにした拡張言語)でReactを書きJavaScriptにトランスパイルすることがある。

ReactはシングルページアプリケーションのWebアプリを開発したり、React Nativeを用いてモバイルアプリを開発するための雛形として使用することができる。複雑なReactアプリケーションでは通常、状態管理・ルーティング・APIとの対話のための追加のライブラリが必要となる。

## 特徴
### 主な特徴
Reactが提供する代表的な機能を以下に挙げる。

* 宣言的UI（テンプレーティング）: JSX
* データバインディング
* コンポーネント化: 関数コンポーネント
* 高効率レンダリング: 仮想DOM

### 他フレームワークとの比較
Reactと立ち位置が近く、競合するフレームワークとして、Vue.js、jQuery、AngularJSなどがある。
Vue.jsはクライアントサイドのJavaScriptによるUI向けライブラリという点では共通しているが、JSXではなくPHP風の置換記法によってHTMLを書き換えたり、双方向バインディングに対応している点が異なり、中小規模のプロジェクトで使われやすい。
jQueryはReactより古く2006年に誕生したライブラリであり、DOM操作によってHTMLを動的に生成するクライアントサイドのJavaScriptライブラリである点はReactと共通しているが、UIの操作について、モデル・ビュー・コントロールを分離するMVCアーキテクチャの設計思想以前に作られ、データの一貫した管理が難しい。2000年代後半から2010年代前半にかけて広く用いられた。
AngularJSは2009年に誕生し、MVCアーキテクチャを採用したクライアントサイドJavaScriptライブラリであり、Googleとコミュニティーが開発していたが、2022年にサポートを終了した。

#### プロパティの一方向データバインディング
プロパティ (通常は`props`) は親コンポーネントからコンポーネントに渡される。コンポーネントは1組のイミュータブルなJavaScriptオブジェクトとしてプロパティを受け取る。

#### ステートフルコンポーネント
`state`はコンポーネントの全体に渡って値を保持し、プロパティを通じて子コンポーネントに渡すことができる。


```js
class ParentComponent extends React.Component {
  state = { color: "green" };
  render() {
    return <ChildComponent color={this.state.color} />;
  }
}
```


#### 仮想DOM
もう1つの注目すべき機能は、仮想DOMの使用である。Reactでは仮想DOMとしてメモリ上にDOMの状態をキャッシュしておき、仮想DOMに差分が発生した場合にのみ差分を計算し、実際のDOMに差分のみを反映させることにより効率的な描画を実現している。これにより、プログラマは変更があるたびにページ全体を描画するコードを記述しながら、Reactライブラリによって実際に変更されたサブコンポーネントのみを描画することができる。

#### ライフサイクルメソッド
ライフサイクルメソッドはコンポーネントの生存期間中に設定した地点で、コードを実行できるようにするためのフックである。
* `shouldComponentUpdate` - 描画が不要な場合に`false`を返すことによって、コンポーネントの不要な再描画を防ぐことができる。
* `componentDidMount` - コンポーネントがマウントされるときに1回だけ呼び出される。これは一般に、APIを介してリモートソースからデータを読み込む際のトリガとして使用されている。
* `render` - 最も重要なライフサイクルメソッドであり、どのコンポーネントでも必要な唯一のものである。このメソッドは、通常はユーザインタフェースの変更を反映して、コンポーネントの状態が更新されるたびに呼び出される。

#### JSX
は、JavaScriptの構文に対する拡張である。HTMLと外観が似ているが、JSXは多くの開発者がよく知っている構文を使用して、構造化されたコンポーネントを描画する方法を提供する。Reactコンポーネントは、必須ではないが、通常はJSXを使用して書かれている。JSXはFacebookがPHP向けに作成した拡張構文であるに似ている。

JSXのコードの例:


```js
const App = () => {
  return (
    <div>
      <p>Header</p>
      <p>Content</p>
      <p>Footer</p>
    </div>
  );
};
```


; 入れ子の要素
同じレベルの複数の要素は、上記の``のように単一のコンテナ要素にラップするか、配列として返す必要がある。
; 属性
JSXはHTMLによって提供されるものを反映するように設計された要素属性の範囲を提供する。カスタム属性もコンポーネントに渡すことができる。全ての属性はコンポーネントによって`props`として受け取られる。
; JavaScriptの式
JavaScriptの式 (文ではない) は、`{}`を使うことによってJSXのコード内に記述することができる。


```js
<h1>{10 + 1}</h1>;
```


上記のコードは下記のように描画される。


```html
<h1>11</h1>
```


; 条件文
if文はJSX内で使用することはできないが、条件式は使用することができる。以下の例では、`i === 1`が評価され、「true」または「false」の文字列が描画される。


```js
const App = ({ i }) => {
  return <div>{String(i === 1)}</div>;
};
```


関数とJSXは条件式内で使用することができる。


```js
const App = () => {
  const sections = [1, 2, 3];
  return (
    <div>
      {sections.map((n) => (
        <div>Section {n}</div>
      ))}
    </div>
  );
};
```


上記は下記のように描画される。


```html
<div>
  <div>Section 1</div>
  <div>Section 2</div>
  <div>Section 3</div>
</div>
```


JSXで書かれたコードはウェブブラウザで実行可能にするために、Babelなどのツールを利用して事前に変換する必要がある。この処理は通常はアプリケーションが配置されるよりも前の、ソフトウェアを構築している段階で実行される。

#### HTML外のアーキテクチャ
Reactは「レンダラーに依存しないこと」を設計原則としている。ゆえにReactはウェブブラウザでHTMLを描画すること（DOMによるレンダリング）以外にも適用される。例えば、Facebookは`[[canvas要素|canvas]]`タグに描画する動的チャートを持ち、NetflixとPayPalではサーバとクライアントの両方で読み込むことができる同一のHTMLを描画するために利用されている。またReact NativeによりネイティブアプリのUIレイヤーとしても機能する。

## 歴史
### 誕生
ReactはFacebookのソフトウェアエンジニアであるJordan Walkeによって開発された。PHP向けのHTMLコンポーネントフレームワークであるの影響を受けている。2011年にFacebookのニュースフィード上で最初に使用され、2012年にはInstagramでも使用されるようになった。2013年5月のJSConf USでオープンソース化された。

### React Native
React NativeはAndroid・iOS・UWPでのReactを利用したネイティブ開発を可能にするもので、2015年2月のReact.js Confで発表され、3月にオープンソース化された。
### React Fiber
2017年4月17日、Facebookはユーザインタフェースを構築するためのReactフレームワークライブラリの新しいコアアルゴリズムであるを発表した。React FiberはReactフレームワークの将来の改良と機能開発の基盤となるものである。

### ライセンス論争
2013年5月に最初に一般公開されたときには標準のApache 2.0を使用していた。2014年10月に公開されたReact バージョン0.12.0からは、Facebookの関連する特許の使用を認める*PATENTS*テキストファイルが追加された、特許条項付きの修正BSDライセンスにライセンスを変更した。

この特許条項はFacebookとその関連企業に対して特許権侵害訴訟した場合に、利用する権利が取り消されるというもので、Reactユーザーコミュニティ内で幾つかの論争と議論を引き起こした。

コミュニティからのフィードバックに基づき、2015年4月にFacebookは特許許諾を曖昧な部分を減らし、より寛容なものになるように変更した。
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系にもバックポートされた。

### 将来の開発
プロジェクトの進捗状況は、コア開発チームのディスカッションフォーラムで見ることができる。しかし、Reactに対する大きな変更についてはreact-futureリポジトリのIssueとプルリクエストを通すことになっている。これによって、Reactコミュニティは将来性のある新しい機能・実験的なAPI・JavaScriptの構文の改善についてのフィードバックを提供することができる。
#### サブプロジェクト
サブプロジェクトの状態についてはプロジェクトのWikiで利用可能だった。

#### Facebook CLA
FacebookはReactの貢献者に対して、Facebookの (CLA) に署名することを要求している。

## 基本的な使い方
以下はJSXとJavaScriptを利用したReactの基本的な使い方である。


```html
<!DOCTYPE html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
```



```javascript
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は完全なアプリケーションフレームワークを提供しようとはしていない。Reactはユーザインタフェースを構築するために設計されており、故に、開発者がアプリケーションを構築する際に必要であると考えるかもしれない多くのツールは含まれていない。このことにより、開発者はネットワークアクセスやローカルデータストレージなどで好みのライブラリを選択することができる。ライブラリが成熟するにつれて、一般的なパターンが明らかになってきた。

#### 単方向のデータフロー
Reactでは単方向のデータフローとしてFluxアーキテクチャが提唱された。Fluxアーキテクチャは、AngularJSの双方向データフローとは対照的なReactの単方向データフローの概念をサポートするために、一般的なMVCアーキテクチャの代替となるものである。Fluxは*Action*が中央*Dispatcher*を介して*Store*に送信され、*Store*に対する変更が*View*に伝播することが特徴である。Reactと共に使用した場合には、この伝播はコンポーネントのプロパティを通じて行われる。

Fluxはオブザーバ・パターンの変種であると考えることができる。

FluxにおけるReactコンポーネントは、渡されたpropsを直接変更せず、Actionを作るコールバック関数が渡される。ActionはDispatcherに送られ、それを元にStoreが更新される。

*Action*は何が起こったのかを説明する義務のあるオブジェクトである。例えば、あるユーザーが別のユーザーをフォローすると記述された*Action*には、自身のユーザーIDと相手のユーザーIDと`USER_FOLLOWED_ANOTHER_USER`が含まれている。*Store*は*Dispatcher*から受け取った*Action*に応じて自身を変更する可能性がある。

このパターンは、「プロパティが下に流れ、アクションが上に流れる」と表現されることがある。多くのFluxの実装がこのアーキテクチャの誕生以来作られてきたが、恐らく最もよく知られている実装は単一の*Store*を特徴とするReduxであり、しばしば信頼できる唯一の情報源と呼ばれている。

## React Native

React Nativeは、本来WebアプリのUI開発のためのフレームワークであるReactを、PCやスマホ向けのネイティブアプリの開発にも使えるようにしたもので、Facebookによって2015年2月に発表された。Android、iOS、Windows（UWP）に対応している。
### 歴史
2012年、Facebookの会長兼CEOであるマーク・ザッカーバーグは、「企業としての最大の失敗は、ネイティブの反対としてHTML5に大きく賭けたことだった。」とコメントしている。彼はFacebookがまもなくより良いモバイル体験を提供することを約束した。

Facebookの社内では、Jordan WalkeがJavaScript製のwebアプリからiOSのUIを生成するシステムのプロトタイプを作り上げており、本格的にReact製Webアプリからネイティブモバイルアプリを構築するために社内ハッカソンが結成された。

数ヶ月の開発の後、FacebookはReact.js Conf 2015で最初のバージョンをリリースした。Christopher Chedeauは技術的な話の中で、FacebookがReact Nativeをグループアプリと彼らの広告管理アプリで既に使用していると説明した。

### 動作原理
React Nativeの動作原理は基本的にはReactと同一だが、ネイティブAPIを利用して描画する点がReactと異なる。React Nativeはバックグラウンドプロセス (開発者の書いたコードを解釈するためのJavaScript処理系) としてエンドデバイス上で直接実行され、シリアライズ可能でかつバッチ処理された*Bridge*を介してネイティブプラットフォームと通信する。

React NativeはHTML5に全く頼らず、全てJavaScriptで書かれており、ネイティブのSDKに頼っている。

### Hello world
React NativeによるHello world:


```js
import React from "react";
import { AppRegistry, Text } from "react-native";

export const HelloWorldApp = () => <Text>Hello world!</Text>;

AppRegistry.registerComponent("HelloWorld", () => HelloWorldApp);
```


## 批判
Reactに対する批判として、仮想DOMの概念を使用しているため、多くのRAMが必要になるというものがある。これは、「UIの表現がメモリ上に保持され、ReactDOMなどのライブラリによって実際のDOMと同期される」ことによるものである。同様に、React バージョン16以降に含まれている仮想DOMの抽象化は、ウェブブラウザに組み込まれているコンポーネントモデルでは上手く動作せず、従って、ウェブブラウザの標準に依存したそれらのコンポーネントを実装する代替ライブラリでは上手く機能しない。

## 脚注
### 注釈

### 出典

## 関連項目

* AngularJS
* Angular
* Gatsby
* Next.js
* Svelte
* Vue.js

## 外部リンク
* 
*