公開日

Next.js でのノイズリダクション

著者

React v16.8 で導入された useEffect を用いた Next.js でのデバウンス

React v16.8 では、関数コンポーネント内で副作用を実行できる新しいフック useEffect が導入されました。useEffect は、API 呼び出しなどの高負荷な操作を処理する優れた方法ですが、少し手間がかかる場合もあります。この記事では、Next.js で useEffect を使用して高負荷な処理をデバウンスする方法を紹介します。

デバウンスとは?

デバウンスとは、関数が呼び出される速度を制御するテクニックです。これは、ユーザーがタイピングを停止したときにのみ実行したい高負荷な操作がある場合に役立ちます。この場合、ユーザーが一定時間タイピングを停止したときにのみ API 呼び出しが行われるように、API 呼び出しをデバウンスすることができます。

useEffect

useEffect は、関数コンポーネント内で副作用を実行できるフックです。これは、クラスコンポーネントの componentDidMountcomponentDidUpdate に似ています。最初の引数は、コンポーネントがマウントまたは更新されたときに呼び出される関数です。2 番目の引数は依存関係の配列です。依存関係が変更されると、処理が再度呼び出されます。配列が空の場合、関数はコンポーネントがマウントされたときにのみ呼び出されます。

import React, { useEffect } from 'react'

const MyComponent = () => {
  useEffect(() => {
    console.log('コンポーネントがマウントされたときに呼び出されます')
  }, [])

  useEffect(() => {
    console.log('コンポーネントがマウントされたときと依存関係が変更されたときに呼び出されます')
  }, [dependency1, dependency2])

  return <div>Hello world</div>
}

Next.js でデバウンスする方法

最初に、デバウンスを処理するカスタムフックを作成する必要があります。簡単な例を以下に示します。

import { useState, useEffect } from 'react'

export default function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value)

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value)
    }, delay)

    return () => {
      clearTimeout(handler)
    }
  }, [value, delay])

  return debouncedValue
}

このフックは、デバウンスする値とミリ秒単位の遅延の 2 つの引数を取ります。デバウンスされた値を返します。このフックは、useEffect を使用して、指定された遅延後にデバウンスされた値を更新するタイムアウトを設定します。また、値または遅延が変更された場合にタイムアウトをクリアするクリーンアップ関数も生成します。

これで、値をデバウンスできるフックができたので、API 呼び出しをデバウンスするために使用できます。例を以下に示します。

import useDebounce from './useDebounce'

export default function Search() {
  const [search, setSearch] = useState('')
  const debouncedSearch = useDebounce(search, 500)

  useEffect(() => {
    if (debouncedSearch) {
      fetch(`/api/search?q=${debouncedSearch}`)
    }
  }, [debouncedSearch])

  return <input type="text" value={search} onChange={(e) => setSearch(e.target.value)} />
}

このコンポーネントは、ユーザーが 500 ミリ秒間タイピングを停止すると、/api/search に API 呼び出しを行います。デバウンスにより、入力フィールドの値をクエリ文字列として使用して API 呼び出しが行われます。

パフォーマンス

デバウンスは、Next.js で高負荷な操作を処理するための安価な方法です。lodash.debounce などのライブラリを使用するよりも安価です。これは、追加の依存関係を必要としないためです。react-throttle などのライブラリを使用するよりも安価です。これは、バンドルする追加のコードを必要としないためです。

まとめ

デバウンスは、関数が呼び出される速度を制御するための貴重なテクニックです。これは、ユーザーがタイピングを停止したときにのみ実行したい高負荷な操作がある場合に役立ちます。この記事では、Next.js で useEffect を使用して高負荷な操作をデバウンスする方法を紹介しました。

この記事がお役に立てば幸いです。JavaScript Hashmap, Performant and Simple もおすすめです。