React HooksにはじまりAlgebraic EffectsだFPだなんだと話題に事欠かない昨今ですが、そういうのは根本から見ていくに限る!ということで。
ReactConf2018のHooksが発表されたセッションを見ながら書いたメモです。
1時間半もあるんやでこの動画・・。
まあ実際は3人のスピーカーが交代で話してるので、3部作だったりする。
React Today
Reactの使命
React Tommorow
課題にどう立ち向かうか
- 1つずつ解決することはできる
- ただし1つが解決すると、もう1つが悪化することもある
- どうしよう?
- ReactがclassコンポーネントよりシンプルなAPIを持ってないのが問題
- Mixinっていう概念が昔あった
- でも失敗だった
- https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
- 新しいナニカが必要
(どういう機能を追加しようとしてるかのデモ)
import React from 'react'; export default class Greeting extends React.Component { constructor(props) { super(props); this.state = { name: 'Mary' }; this.onChangeName = this.onChangeName.bind(this); } onChangeName(ev) { this.setState({ name: ev.target.value }); } render() { return ( <section> <input value={this.state.name} onChange={this.onChangeName} /> </section> ); } }
- これを、Functionalコンポーネントでやりたい
- Hooksと呼んでる仕組みで解決すると、こう書ける
import React, { useState } from 'react'; export default function Greeting(props) { const [name, setName] = useState('Mary'); function onChangeName(ev) { setName(ev.target.value); } return ( <section> <input value={this.state.name} onChange={this.onChangeName} /> </section> ); }
- この2つの例の違い
- classコンポーネントの場合
- `this`によるアクセスが発生
- `state`はオブジェクト
- `handler`も別途定義が必要
- Hooksを使う場合
- `this`は存在しない
- `state`と`handler`は都度用意する
- `state`と`handler`はペアになってる
Hooks
- 何がしたいのかがわかりやすい
- あれこれやっちゃう関数みたいなのは作れない
- `state`なら`state`のことだけやる
- Lifecycleフックの中でごちゃごちゃもできない
- Hooksは呼び出し順に依存する
- なので`if`の中に書いたりはできない
- Linterで検知できる
- Hooksは他にも種類がいくつかある
`useContext()`
- Context APIを使える
- Render propsではなくダイレクトに変数にできる
- つまりネストが減る
`useEffect()`
- Lifecycleフックの代わりになる
- 中でReactが用意してないことをする
- そのコンポーネントのスコープの内容を使って何かする
- 複数のことをやりたい場合は複数のHooksにする
- 役割を持たせすぎないことを推奨
- 関数を返すと、それが`componentWillUnmount()`の代わりになる
チューニング
- この調子でHooksを増やしていくと、コードは肥大化する
- しかし幸いなことにこれらはすべてただの関数!
- 切り出して使うことができる
- `useXxx()`として切り出すのを推奨
- CustomHooksと呼んでる
- もちろん引数も渡せる