Edited at

React Custom Hooksのサンプル集

※ 本記事は useState, useEffect, useContext 等の Built-in Hooks については理解していることを前提としています。

React v16.8 でリリースされる予定(元はv16.7だったが延期)の Hooks 機能ですが、その醍醐味は Custom Hooks にあると思います。

しかし慣れない内は Custom Hooks を作るのは難しいと思いサンプルを集めました。眺めることで Custom Hooks の勘所のようなものが掴めればいいなと。


TL;DR

サンプル集のセクションを参照


Custom Hooksとは

Custom Hooksとは特定の Hooks API のことではなく、それらを組み合わせて作る独自のHooksです。

簡単な例をあげてみます。

メールアドレスとパスワードがある入力フォームの場合、 Built-in Hooks だけを使って書くと次のようになると思います。

() => {

const [email, setEmail] = useState("")
const [password, setPassword] = useState("")

return (
<form>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value) } />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value) } />
</form>
)
}

React v16.7 以前と比較すると、スマートにかけるようになりましたが、冗長な部分がありますよね。

そこで Custom Hooks の出番です。

const useInput = initialValue => {

const [value, set] = useState(initialValue)

return { value, onChange: (e) => set(e.target.value) }
}

() => {
const emailProps = useInput("")
const passwordProps = useInput("")

return (
<form>
<input type="email" {...emailProps} />
<input type="password" {...passwordProps} />
</form>
)
}

useInput という Custom Hook を作ることでより簡潔に書くことができました。(簡単な例であまりメリットを感じないかも知れませんが)


サンプル集


React Hooks 大喜利 Advent Calendar 2018

2018年の Advent Calendar で何とお一人で23個のパターンを見せてくれました。(他の2日は導入等の前置き的な記事)

モダンなUIやアニメーションを Custom Hooks でどう実装するのかという点が大変勉強になりました。(もちろんそれだけではありませんよ)

Qiitaの記事では考え方とか設計方法の説明に重点が置かれており、掲載コードは一部省略されています。本気で勉強したい場合は Github のリポジトリ をcloneして実コードと並べて読むといいと思います。(私もカレンダー期間中はほぼ毎日、アプリを動かしながら実コードとQiita記事を読みながらフムフム言ってました)

余談ですけど、useRef を通常用途とは異なる使い方をされていて、「なるほどなぁ、そういう使い方もできるのか」と感銘を受けたんですけど、今検索しても見つけられず・・・記憶違いかなぁ。

通常は const ref = useRef(); return <div ref={ref} /> のような使い方をされると思いますが、たしかその記事ではプリミティブな値(少なくとも HTMLElement ではない)を扱っていて、代入も自前でやってたはず。


useHooks - Easy to understand React Hook recipes

useHistory, useKeyPress 等、どちらかと言えば機能的な Custom Hooks が16パターン紹介されています。


Building a GraphQL HOC with React Hooks - wawhal - a personal blog

GraphQL のクエリを扱うサンプル。(1パターンだけ)


Making setInterval Declarative with React Hooks — Overreacted

Custom Hooks で setInterval を扱うパターン。(おそらく当たり前過ぎて記事中では触れられていないけど setTimeout も同じ考え方)

要点としては、以下の感じ。


  • コールバック関数は useRef で参照を保持しておく。(コールバック関数が変わるたびに参照も変える)


  • useEffectsetInterval (or setTimeout) して、その戻り値( intervalId (or timerId) ) を clearInterval (or clearTimeout) する関数を返す。遅延時間が変わるたびに setInterval (or setTimeout) で登録しなおす。

要点と言いつつ、コードをそのまま日本語にした感じになってしまった


react-hooks-async

react-hooks-async は npm ライブラリだけど、非同期処理の扱いの参考になる。

遅延処理(timeout, delay) や通信処理(fetch, axios)のほか、WebAssembly なんかも扱っている。

ちなみに1hook(1ファイル)あたり数十行〜百行未満なので、読みやすく理解もしやすい。

前出の「Making setInterval Declarative with React Hooks — Overreacted」の内容に加え、非同期処理の中断(abort)機能も実装されている。


React Portals with Hooks

モーダル表示などでよく使われる Portal (ReactDOM.createPortal) との組み合わせ。


10 Custom React Hooks you Should Have in Your Toolbox

npm ライブラリ群の紹介記事だけど、使用例を見るとライブラリの中でどういったことをやっているかは何となく想像でき参考になる。


Collection of React Hooks

タイトル通り、Hooksのコレクション。名称での検索以外にも tag:fetch のようにタグ検索や、 hook:useState のようにBuilt-in Hooks での検索もできる。

たとえば「useRefは実際にはどのような使われ方しているんだろう」というような視点で参考になるかも。


最初は上記リンクで紹介されているパターン1つずつ概要を書こうと思ったんですが、 途中で挫折 下手な説明よりも実際にコードを見てもらうのが早いと思い、ルートページのリンクのみとしています。

他にも見つけたら追加していきます。もしおすすめのサンプル集などありましたら教えてください。