# 今週何知った? 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) ## メモ欄