JavaScriptは関数を第一級市民として扱います。 そして、バージョン16.8でフックが導入されたことで、これがReactでこれまで以上に確認できるようになりました。 それらは、機能コンポーネントに対する状態操作と副作用を考慮に入れています。

Gatsbyは、その中核として、すべての機能を備えたバニラReactを使用しています。 つまり、フックはシンプルなもので使用できるということです import 声明。 それらを利用する方法のいくつかを見てみましょう。

入門

特に何もありません。インストールする必要があります。 ただし、最新バージョンのReactとGatsby、または少なくともv16.8以降が必要です。 これを行うには、 package.json をチェックして、既にインストールされているバージョンを見つけます。

アップグレードが必要な場合は、以下を実行できます。

$ npm install [email protected] [email protected]
# or
$ yarn add [email protected] [email protected]

それで、私たちは行ってもいいはずです。

フックの使用

を設定しましょう header.js スクロール状態とドロップダウンメニューを備えたコンポーネント。

コンポーネントは上部に固定されたヘッダーであり、ユーザーがページをスクロールしている間はそのまま残りますが、ユーザーが上部にいない場合はボックスシャドウが表示されます。 つまり、現在のウィンドウ位置に基づいて切り替わるブール値が状態になります。 ネイティブAPIを使用してウィンドウの位置を決定します。

src / components / header.js
import React, { useState, useEffect } from 'react';
import { Link } from 'gatsby';

const Header = () => {
  // determined if page has scrolled and if the view is on mobile
  const [scrolled, setScrolled] = useState(false);

  // change state on scroll
  useEffect(() => {
    const handleScroll = () => {
      const isScrolled = window.scrollY > 10;
      if (isScrolled !== scrolled) {
        setScrolled(!scrolled);
      }
    };

    document.addEventListener('scroll', handleScroll, { passive: true });

    return () => {
      // clean up the event handler when the component unmounts
      document.removeEventListener('scroll', handleScroll);
    };
  }, [scrolled]);

  return (
    <header data-active={scrolled}>
      <Link to="/">React Hooks on Gatsby</Link>
      <nav>
        <Link to="/about/">About</Link>
        <Link to="/contact/">Contact Us</Link>
      </nav>
    </header>
  );
};

export default Header;

window.scrollY プロパティは、スクロール時に垂直方向に通過したピクセル数を返します。 その値を10ピクセルと比較すると、ユーザーがドキュメントを移動したかどうかを示すブール値が得られます。 次に、条件付きプロパティを、更新する関数の周りにラップします。 scrolled ユーザーがサイトをスクロールするたびに状態を示します。 次に、この関数はドキュメントのイベントリスナーに渡されます。

これらはすべてuseEffectフック内に存在し、 removeEventListener コンポーネントがアンマウントされたときにイベントハンドラーをクリーンアップするためにドキュメント上で。 useEffect フックを使用すると、コンポーネントに副作用を実行できます。 デフォルトでは、レンダリングが完了するたびにエフェクトが起動しますが、エフェクトの起動に依存する値の配列として2番目の引数を渡すことができます。 私たちの場合には、 [scrolled].

これで、HTMLに識別属性を追加して、要素の状態を判別できます。 を使用します data-active からのブール値を持つ属性 scrolled 州。 そして私たちのCSSでは、 box-shadow 属性セレクターを使用した効果。

src / styles / main.scss
header {
  position: fixed;
  top: 0;
  transition: box-shadow .3s ease;
  width: 100%;

  &[data-active='true'] {
    box-shadow: 0 2px 8px rgba(152,168,188,.2);
  }
}

styled-componentsでも同じスタイルを使用できます。 スワッピング header コンポーネントのタグ付きテンプレートリテラルを備えたセレクターは、同じ機能を提供します。

フックとユーザー入力

この例をさらに一歩進めて、トグルボタンからアクセスできるドロップダウンメニューを追加します。 すでに作成されたもののほとんどを保持し、状態変更プロパティを変更するだけです。 プロパティの名前が次のように変更されます statesetState さまざまな状態変数を使用してオブジェクトを取得します。

この場合、更新状態は少し異なります。 最初に、前の状態をスプレッド演算子として渡し、その後に更新された値を渡す必要があります。 これは、クラスコンポーネントとは異なり、機能コンポーネントは更新されたオブジェクトをマージするのではなく置き換えるためです。

src / components / header.js
import React, { useState, useEffect } from 'react';
import { Link } from 'gatsby';

import Dropdown from './dropdownMenu';

const Header = () => {
  // determined if page has scrolled and if the view is on mobile
  const [state, setState] = useState({
    scrolled: false,
    visible: false,
  });

  // change state on scroll
  useEffect(() => {
    const handleScroll = () => {
      const isScrolled = window.scrollY > 10;
      if (isScrolled !== state.scrolled) {
        setState({
          ...state,
          scrolled: !state.scrolled,
        });
      }
    };
    document.addEventListener('scroll', handleScroll, { passive: true });
    return () => {
      // clean up the event handler when the component unmounts
      document.removeEventListener('scroll', handleScroll);
    };
  }, [state.scrolled]);

  // toggle dropdown visibility
  const toggleVisibility = () => {
    setState({
      ...state,
      visible: !state.visible,
    });
  };

  return (
    <header data-active={state.scrolled}>
      <Link to="/">React Hooks on Gatsby</Link>
      <nav>
        <Link to="/about/">About</Link>
        <Link to="/contact/">Contact Us</Link>
        <button onClick={toggleVisibility} type="button">
          Solutions
        </button>
        <Dropdown
          aria-hidden={!state.visible}
          data-active={state.visible}
        />
      </nav>
    </header>
  );
};

export default Header;

追加のメニューを開くボタンをクリックするようにユーザーに指示します。 ソリューションボタンをクリックすると、 visible ブール値。 このブール値はに渡されます aria-hiddendata-active CSSで使用する属性。

src / styles / main.scss
// the section element is our <Dropdown /> component

header {
  top: 0;
  transition: box-shadow .3s ease;

  &[data-active='true'] {
    box-shadow: 0 2px 8px rgba(152,168,188,.2);
  }

  &,
  section {
    position: fixed;
    width: 100%;
  }

  nav,
  section {
    overflow: hidden;
  }

  section {
    height: 0;
    left: 0;
    opacity: 0;
    right: 0;
    top: 5.5rem;
    transition: all .3s ease-in-out;
    visibility: hidden;

    &[data-active='true'] {
      height: auto;
      opacity: 1;
      visibility: visible;
    }
  }
}

結論

フックを使用すると、機能的なコンポーネントに精通しているクラスコンポーネントのすべての利点を得ることができます。 ギャツビーはそれを最大限に活用しています。 Reactのドキュメントで利用可能なすべてのフックを確認することをお勧めします。 また、独自のフックの作成に飛び込むこともできます。