対象読者
- JavaScriptとWeb開発の基礎に理解がある方
- Reactを用いたJavaScriptアプリケーション開発の未経験者
前提環境
筆者の検証環境は以下の通りです。
- macOS Catalina 10.15
- Node.js 11.7.0/npm 6.5.0
- expo-cli 3.0.10
- expo 34.0.1
- React 16.8.3
関数コンポーネントを高機能にする
第3回で、Reactのコンポーネントの作り方にはクラスコンポーネントと関数コンポーネントの2種類があることを解説しました。また、クラスコンポーネントにはライフサイクル管理や状態管理の仕組みが組み込まれていることを、前回解説しました。
さて、これまで本連載で解説してきた範囲では、関数コンポーネントは「引数であるpropsに応じて決まったJSXを返す関数」でした。リスト1は簡単な関数コンポーネントの例です。
function Welcome(props) { return <Text>Hello, {props.name}</Text>; }
クラスコンポーネントで同様の機能を実現する場合に比べると、関数コンポーネントではいくらか記述量やインデントの深さが減るので、コード全体の見通しがよくなるといった利点があります。一般に、できる限り、UI記述の多くの部分を関数コンポーネントで実装したほうが、コードの可読性は上がっていきます。
しかし、UIの組み合わせをアプリケーションとして成立させるためには、状態管理やライフサイクル管理が不可欠です。どんなに関数コンポーネントだけでアプリケーションを作りたくても、これらの機能を利用するためだけにクラスコンポーネントを使うことを、以前の私たちは強いられていました。
そんな状況は長くは続きませんでした。Facebook社のReact開発チームも、できるだけ関数コンポーネントだけでアプリケーションを作りたいと思っていたようで、関数コンポーネントをリッチにするためのツールが発明されました。それがReact 16.8で実装された、Hooks(フックス)と呼ばれる関数群です。日本語版ドキュメントでの呼び方に倣って、本記事では「フック」と表記します。
現在では、私たちはクラスコンポーネントと関数コンポーネントを、おおむね同等の機能を実現できる対等な存在として、選択することができるようになりました。本記事では、フックを用いて関数コンポーネントをリッチに扱う方法を解説していきます。
フック
フックの個別の関数について、役割と使い方について解説していきますが、百聞は一見にしかずということで、まずはリスト2のサンプルをご覧ください。前回はクラスコンポーネントで解説した、カウンターアプリの関数コンポーネント版です。
import React, { useState } from 'react'; // (2) import { Text, View, Button } from 'react-native'; export default function App() { const [count, setCount] = useState(0); // (1) return ( <View style={styles.container}> <Button title="-1" onPress={() => setCount(count - 1)} /> <Text>{count}</Text> <Button title="+1" onPress={() => setCount(count + 1)} /> </View> ); };
(1)で実行されている useState
は、フックの1つで、状態管理を行います。また、(2)で react
からインポートしていることから、Reactライブラリの一機能であることが分かりますね。
フックの関数は、慣例として useXxxxx
という形で命名することになっています。Reactライブラリが直接提供しているフックはこの命名に従っていますし、それらを組み合わせて自作する独自フック(後述します)も、 useXxxxx
の命名規則に従うべきです。Reactアプリケーションを開発する中で useXxxxx
という名前を見かけたら、フックのことだと思ってよいでしょう。
組み込みフック
Reactに組み込まれているフックは10種類あります。多くのフックは慣れるまで使わないため、公式ドキュメントでは基本のフック、追加のフック、と分類されています。次の2つの表で簡単に列挙します。
フック | 概要 |
---|---|
useState | 状態を管理する |
useEffect | ライフサイクルに基づいた副作用を管理する |
useContext | Context APIから渡された値を取り出す |
フック | 概要 |
---|---|
useReducer | useStateよりも複雑な状態を扱う |
useCallback | コストが高い関数生成の実行回数を抑える |
useMemo | コストが高い値生成の実行回数を抑える |
useRef | DOMやその他のオブジェクトへの参照を保持する |
useImperativeHandle | 親コンポーネントへ渡す参照を加工する |
useLayoutEffect | DOMの更新後に同期的に呼び出される副作用を管理する |
useDebugValue | React DevTools でカスタムフックのラベルを表示する |
これらの中で、実用上、本当によく使うのは useState
と useEffect
の2つだけです。同じく基本のフックである useContext
も、ライブラリを作る際には頻繁に利用するものの、アプリケーションを作る際にはほとんど使いません。そのため、本記事では useState
と useEffect
の2つを中心に解説します。