フック

React16.8から導入されたフックの基本を学びます。

概要

簡単に言うと、関数型のコンポーネントにstateを持たせる仕組みのことです。以下、公式ドキュメントからの引用です。

フックとは、関数コンポーネントに state やライフサイクルといった React の機能を “接続する (hook into)” ための関数です。

フックのコード例

以下に、フックを利用した場合のコード例を示します。
やっていることは単純で、ボタンを押すたびに画面上のカウンタがインクリメントされていきます。

import React, {useState} from 'react';

//フックを使用した例
export function Counter3() {
  const [count, setCount] = useState(0);

  return(
    <div>
      <p>you clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}> click me</button>
    </div>
  )
}

解説

import React, {useState} from 'react';の部分でインポートしているuseStateがフックとなります。
useStateは、初期値となる値をひとつ引数にとり、初期化するstateと、stateを更新する関数を返します。 この場合、countが0で初期化され、setCountにより、stateを更新できるようになる、ということです。

フックの基本の使い方

最初からあれやこれやと手を出すよりも、まずは公式ドキュメントにある基本のフックを学びましょう。

useState

先ほどのカウンタで行ったものです。
const [state, setState] = useState(initialState)の形式でstateの初期値と、更新するための関数を定義します。
setState()を呼び出すことでstateの更新ができます。

useEffect

useEffectを使用すると、関数のレンダー後に副作用を起こすことができます。
以下は、前述したカウンタについて、副作用としてタイトルにカウント回数をレンダーします。

  useEffect(() => {
    document.title = `you clicked ${count} times`;
  });

useContext

useContextを知る前に、そもそもReactにおけるContextの使用方法を学ぶべきですね。 公式ドキュメントによれば、

コンテクストは各階層で手動でプロパティを下に渡すことなく、コンポーネントツリー内でデータを渡す方法を提供します。

とのことです。平たくいうと、通常はpropsを用いることで親から子へ子から孫へ・・という形で実現していたことを、明示的にpropsを利用しなくとも値を渡すことができる仕組みのようです。

さて、useContextの話に戻ります。
以下、公式ドキュメントからの引用コードになります。(importなど、一部実行させるために手を加えています。)

import React, {useContext} from 'react'

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

//Contextの生成
const ThemeContext = React.createContext(themes.light);

export function App2() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

//中間であるToolbarでは、値の中継を明示的にしなくとも良い
function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  //useContextを使用して現在のContextを取得する
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

上記のコードでは、親であるApp2から、孫にあたるThemedButtonまで、値を引き渡すことに成功しています。子にあたるToolbarではContextを明示的に扱っていないことがポイントになります。

終わりに

以上、簡単ではありますがフックの使い方についてでした。
フックをはじめ、Reactはまだまだ勉強しないといけないことが多いですね。

それでは。