---
# System prepended metadata

title: '今週何知った？ week:17'

---


# 今週何知った？ week:17

## 各自発表


> [name=makicamel]

## React の関数コンポーネントとクラスコンポーネント

以前は関数コンポーネントでは state やライフサイクルをサポートしていなかったが React16.8 からサポートされるようになった。公式でも関数コンポーネントを推奨している

### 関数コンポーネント・クラスコンポーネントとは
- 関数コンポーネント
  - JSX を返すプレーンな JavaScript 関数
  ```javascript
    import React from "react";
    const FunctionalComponent = ({ name }) => {
      return <h1>Hello, { name }</h1>;
    };
  ```
- クラスコンポーネント
  - `React.Component` を拡張する JavaScript クラス
  ```javascript
  import React, { Component } from "react";
  class ClassComponent extends Component {
    render() {
      // クラスなので this を使用し props を参照する必要がある
      const { name } = this.props;
      return <h1>Hello, { name }</h1>;
    }
  }
  ```

### state 処理
State とはコンポーネントのレンダリングを操作するオブジェクトの事

- 関数コンポーネント

```javascript
const FunctionalComponent = () => {
  const [count, setCount] = React.useState(0);  // 初期値を受け取る
  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Click</button>
    </div>
  )
}
```

- クラスコンポーネント  
> Reactコンポーネントのコンストラクタは、マウントされる前に呼び出されます。React.Componentサブクラスのコンストラクタを実装する場合は、他の記述よりも前にsuper(props) を呼び出す必要があります。こうしないと、コンストラクタでthis.propsが定義されず、バグになります
> https://reactjs.org/docs/react-component.html#constructor
```javascript
class ClassComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
 }
 render() {
   return (
     <div>
       <p>count: {this.state.count} times</p>
       <button onClick={() => this.setState({ count: this.state.count + 1 })}>
         Click
       </button>
     </div>
   );
}
```

### ライフサイクル

Lifecycle とは、Mounting(マウント)、Updating(更新)、Unmounting(アンマウント)の一連の流れの事

#### マウント時(componentDidMount)
`componentDidMount` は最初のレンダリング後に 1 回呼び出されるライフサイクルメソッド

- 関数コンポーネント

```javascript
const FunctionalComponent = () => {
  React.useEffect(() => {
    console.log("Hello");
  }, []); // 第二引数には変更される state の配列が入る
  return <h1>Hello, World</h1>;
};
```

- クラスコンポーネント

```javascript
class ClassComponent extends React.Component {
  componentDidMount() {
    console.log("Hello");
  }
  render() {
    return <h1>Hello, World</h1>;
  }
}
```

#### マウント解除時(componentWillUnmount)

- 関数コンポーネント  
  - マウント解除時に実行される関数を返す必要がある。サブスクリプションのクリーンアップが必要な場合などにべんり
  - マウント・アンマウントの処理を同じ関数で行える

```javascript
const FunctionalComponent = () => {
  React.useEffect(() => {
    return () => {
      console.log("Bye");
    };
  }, []);
 return <h1>Bye, World</h1>;
};
```

- クラスコンポーネント

```javascript
class ClassComponent extends React.Component {
 componentWillUnmount() {
   console.log("Bye");
 }

 render() {
   return <h1>Bye, World</h1>;
 }
}
```

## 参考
[React:関数コンポーネントとクラスコンポーネントの違い](https://www.twilio.com/blog/react-choose-functional-components-jp)


### React hook

- hook とは
  - React 16.8 で追加された機能。state などの React の機能をクラスを書かずに使えるようになる
  - 関数コンポーネントに state やライフサイクルといった React の機能を "接続する" (hook into) ための関数
  - 関数コンポーネントで state を扱うためのフックを「ステートフック」と呼ぶ
https://ja.reactjs.org/docs/hooks-overview.html


> [name=ken3ypa]

# Hotwire
公式：https://hotwired.dev/
- HTML over the wire（ネットワーク越しのHTML）の略
- レスポンスをJSONではなくHTMLで受け取る

## 構成
- Turbo
    - Turbo Drive
    - Turbo Frames
    - Turbo Streams
- Stimulus
- Strada

## 今回は Turboのみ触れる

### Turbo Drive
- Turbolinksの後継
- リンクやフォーム送信などに発生する画面遷移を高速にする

#### 処理の流れ
- フォームからリクエストが飛ぶ
- FetchAPIによる非同期リクエストに差し替え
- レスポンスされたHTMLのbodyだけを抜き出して、現在のページの<body>に差し替える

#### メリット
- 今のページのCSS・JSをそのまま利用できるため、ページの初期化コストが下がる
    - Basecampでは処理が三倍早くなったとのこと

 #### Turbolinksとの違い
- リンクだけでなくフォームも扱うようになった
- [イベント名の変更](https://zenn.dev/shita1112/books/cat-hotwire-turbo/viewer/turbo-drive#%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E5%90%8D%E3%81%AE%E5%A4%89%E6%9B%B4)
- [Turbo Drive｜猫でもわかるHotwire入門 Turbo編](https://zenn.dev/shita1112/books/cat-hotwire-turbo/viewer/turbo-drive#%E3%82%AF%E3%83%A9%E3%82%B9%E5%90%8D%E3%81%AE%E5%A4%89%E6%9B%B4)

### Turbo Frames
- Turbo Drive の部分置換
- ページ内の置換や遅延読み込みができるようになる

|Turbo Drive|Turbo Frame|
| --- | --- |
| body全体を置換 | turbo-frame のtarget のみを置換 |

    
## 利点
- 一部のみSPAを取り入れたい場合に便利
    - NoJavaScriptでSPA
    - MPAだが一部SPAという構成に最適
- HTMLをそのまま返す
    - RailsのView側の資産がそのまま使える
    - デザイナーと協業しやすい

## 所感
- 一気通貫で同じフレームワーク・言語で実装できればいいのに、はわかる
    - MPAにVue.jsをちょっと乗っけるパターンよりはHotwireの方が便利そう
- 一方でフロントエンドエンジニアとして触るにはつらそう
    - いろんなものが隠蔽されている
    - 他のフレームワークで培ったノウハウがあまり活きなさそう

 ## その他読み物：
- [Rails 7.0 で標準になった importmap-rails とは何なのか？](https://zenn.dev/takeyuweb/articles/996adfac0d58fb)
- [妄想的DHH理解 - Qiita](https://qiita.com/nazomikan/items/eab3352dbd5e2b79724b)
- [妄想的DHH理解2:概念的距離の圧縮 - Qiita](https://qiita.com/nazomikan/items/a89391dd08dec6adc9c6)
- [Rails7のフロントエンドの方向性について理解したことをメモ - kasei_sanのブログ](https://blog.kasei-san.com/entry/2021/10/07/085008)
- [Hotwireとは何なのか？](https://zenn.dev/en30/articles/2e8e0c55c128e0)
- [猫でもわかるHotwire入門 Turbo編](https://zenn.dev/shita1112/books/cat-hotwire-turbo)
    
## メモ欄
