【フロントエンド】AngularとReactのいろいろ対応表

Angularは知ってるけどReactはまだこれから、
あるいはその逆というときに使えるような、
両フレームワークの類似点をまとめた表を作ってみました。

自分はReactを勉強中で、随時更新していく予定です。
個人的にはAngularもReactもより好きになっていく予感がしています。

### 確認時の各バージョン

| 項目 | バージョン |
|:-:|:-:|
| OS  | windows10  |
| node.js  | 14.16.1  |
| [Angular CLI](https://www.npmjs.com/package/@angular/cli)  | 11.2.9  |
| [create-react-app](https://www.npmjs.com/package/create-react-app)  | 4.0.3  |

### 注意

- 一部、見やすくするために閉じタグ`</...>`を省略して記述しています。
- 任意の変数などの名称は代わりとして`any`を含ませた文字列で記述しています。
- typescriptを使っています。
- 細かいところなど不足があると思います。間違いなどあればご指摘お願いします。

## CLI, コマンドなど

| 説明 | Angular | React |
|:-:|:-:|:-:|
| npmパッケージ  | `@angular/cli`  | `create-react-app`  |
| プロジェクト新規作成  | `> ng new any-project`  | `> npx create-react-app any-project --template typescript`  |
| 実行  | `> npm start`  | `> npm start`  |
| ポート番号  | `4200`  | `3000`  |

## 追加モジュール

| 説明 | Angular | React |
|:-:|:-:|:-:|
| ディレクティブに渡す値の型の管理  | 不要  | [prop-types](https://www.npmjs.com/package/prop-types)  |
| ルーティング  | 不要  | [react-router-dom](https://www.npmjs.com/package/react-router-dom), [@types/react-router-dom](https://www.npmjs.com/package/@types/react-router-dom)  |
| その他  | 基本的に不要  | 必要に応じて要追加  |


## 文法

| 説明 | Angular | React |
|:-:|:-:|:-:|
| 描画されないタグ  | `<ng-container>`  | `<React.Fragment>` または `<>`  |
| 子のタグ  | `<app-any-component>`  | `<AnyComponent>`  |
| class属性  | `class=""`  | `className=""`  |
| for属性  | `for=""`  | `htmlFor=""`  |
| style属性  | `style="width: 100px; background-color: #FAFAFA;"`  | `style={{width: '100px', backgroundColor: '#FAFAFA'}}`  |
| その他属性  | `any-property=""`  | `anyProperty=""`  |
| コメント  | `<!-- -->`  | `{/* */}`  |
| 属性に式の結果を渡す  | プロパティバインディング<br/>`[属性]="式"`<br/><br/>例）`<img [src]="anySrc" />`  | 式の埋め込み<br/>`属性={式}`<br/><br/>例）`<img src={anySrc} />`  |
| イベントを扱う  | イベントバインディング<br/>`(イベント)="式"`<br/><br/>例）`<button (click)="anyFunction($event)">`  | イベントハンドリング<br/>`イベント={イベントハンドラ}`<br/><br/>例）`<button onClick={this.anyFunction.bind(this)}>`  |
| テンプレートに式を書く  | インターポレーション（補間）<br/>`{{ }}`  | 式の埋め込み<br/>`{ }`  |
| htmlなどのセーフティ解除  | `DomSanitizer`  | `dangerouslySetInnerHTML`  |

## コンポーネント間の情報伝達

| 説明 | Angular | React |
|:-:|:-:|:-:|
| 親から子へ  | `@Input()`<br/><br/>例）親: `<app-child-component url="/any">`<br/><br/>子: `@Input() url = ''`,<br/>`<p>{{url}}</p>` | `this.props`, `propTypes`<br/><br/>例）親: `<ChildComponent url="/any">`<br/><br/>子: `<p>{this.props.url}</p>`  |
| 子から親へ  | `@Output()`, `EventEmitter`, イベントバインディング, `$event`<br/><br/>例） 子: `@Output() anyAction = new EventEmitter()`,<br/>`anyAction.emit(anyValue)`<br/><br/>親: `<app-child-component (anyAction)="anyFunction($event)">`   | `props`, `state`, `setState()`, イベントハンドリング, `bind()`<br/><br/>例）子: `this.props.onAnyAction(this.state)`<br/><br/>親: `<ChildComponent onAnyAction={this.anyFunction.bind(this)} />`  |
| 外部コンテンツ  | `<ng-content>`  | `{this.props.children}`  |

## 条件分岐、繰り返し処理

| 説明 | Angular | React |
|:-:|:-:|:-:|
| 分岐処理  | `*ngIf`, `*ngTemplateOutlet`, `ngSwitch`, `ngPlural`  | 三項演算子, `&&`演算子, 即時関数, 関数化  |
| 繰り返し処理  | `*ngFor`<br/><br/>例）`<app-any-component item="item" *ngFor="let item for items">`  | `map()`<br/><br/>例）`items.map(item => <AnyComponent item={item} />)`  |
| リスト要素の追跡  | `trackBy: トラッキング式`  | `key`属性  |

## ライフサイクルメソッド

| 説明 | Angular | React |
|:-:|:-:|:-:|
| コンストラクター（一度のみ）  | `constructor()`  | `constructor()`  |
| 親コンポーネントからデータを（再度）受け取った後  | `ngOnChanges()`  | -  |
| コンポーネントの初期化時（一度のみ）  | `ngOnInit()`  | `componentDidMount()`  |
| 状態の変更の検出時  | `ngDoCheck()`  | `shouldComponentUpdate()`  |
| 外部コンテンツの初期化時（一度のみ）  | `ngAfterContentInit()`  | -  |
| 外部コンテンツの更新チェック時  | `ngAfterContentChecked()`  | -  |
| 子を含むビューの生成時（一度のみ）  | `ngAfterViewInit()`  | -  |
| 子を含むビューの更新時  | `ngAfterViewChecked()`  | `componentDidUpdate()`  |
| コンポーネントが破棄される時  | `ngOnDestroyed()`  | `componentWillUnmount()`  |

## ルーティング

| 説明 | Angular | React |
|:-:|:-:|:-:|
| ルーティング用ファイルの有無  | `any-routing.module.ts`に記述  | 必要に応じて任意のファイルに分割可能  |
| リンク  | `<a routerLink="/">`  | `<Link to="/">`  |
| lazy loading  | 可能  | 可能  |