GatsbyでのReactフックの使用
JavaScriptは関数を第一級市民として扱います。 そして、バージョン16.8でフックが導入されたことで、これがReactでこれまで以上に確認できるようになりました。 それらは、機能コンポーネントに対する状態操作と副作用を考慮に入れています。
Gatsbyは、その中核として、すべての機能を備えたバニラReactを使用しています。 つまり、フックは単純なimport
ステートメントで使用できるということです。 それらを利用する方法のいくつかを見てみましょう。
入門
特に何もありません。インストールする必要があります。 ただし、最新バージョンのReactとGatsby、または少なくともv16.8以降が必要です。 これを行うには、 package.json をチェックして、既にインストールされているバージョンを見つけます。
アップグレードが必要な場合は、以下を実行できます。
$ npm install react@16.8.0 react-dom@16.8.0 # or $ yarn add react@16.8.0 react-dom@16.8.0
それで、私たちは行ってもいいはずです。
フックの使用
スクロール状態とドロップダウンメニューを備えた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に識別属性を追加して、要素の状態を判別できます。 scrolled
状態のブール値でdata-active
属性を使用します。 また、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
セレクターをコンポーネントのタグ付きテンプレートリテラルと交換すると、同じ機能が提供されます。
フックとユーザー入力
この例をさらに一歩進めて、トグルボタンからアクセスできるドロップダウンメニューを追加します。 すでに作成されたもののほとんどを保持し、状態変更プロパティを変更するだけです。 さまざまな状態変数を持つオブジェクトを取得している間、プロパティの名前はstate
およびsetState
に変更されます。
この場合、更新状態は少し異なります。 最初に、前の状態をスプレッド演算子として渡し、その後に更新された値を渡す必要があります。 これは、クラスコンポーネントとは異なり、機能コンポーネントは更新されたオブジェクトをマージするのではなく置き換えるためです。
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;
追加のメニューを開くボタンをクリックするようにユーザーに指示します。 Solutions ボタンをクリックすると、visible
ブール値が切り替わります。 このブール値は、CSSで使用するためにaria-hidden
およびdata-active
属性に渡されます。
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のドキュメントで利用可能なすべてのフックを確認することをお勧めします。 また、独自のフックの作成に飛び込むこともできます。