Algolia InstantSearchの検索を、独自のformタグで実装する(React編)

AlgoliaのReact Instantsearch Hooksを使って、任意のタイミングで検索を実行するの応用編です。 前の記事でやったこと useInstantSearch()フックを利用して、任意のタイミングで検 […]

広告ここから
広告ここまで

目次

    AlgoliaのReact Instantsearch Hooksを使って、任意のタイミングで検索を実行するの応用編です。

    前の記事でやったこと

    useInstantSearch()フックを利用して、任意のタイミングで検索を実行できるようにしました。

    const indexName = 'YOUR_ALGOLIA_IDNEX_NAME'
    const { uiState, setUiState } = useInstantSearch()
    
    const searchCustom = (word: string) => {
      setUiState({
        ...uiState,
        [indexName]: {
          ...uiState[indexName],
          query: word,
        },
      })
    }

    やりたかったこと

    Tailwind UIIonic Frameworkなどを使うと、FWが提供する検索コンポーネントを使いたい場合があります。

    useInstantSearch()フックを利用すると、簡単な検索フォームを独自実装できます。

    以下はNext.js+Tailwindのサンプルの抜粋です。

    export const HeaderSearchForm: FC = () => {
      const { push, pathname } = useRouter()
      const [word, setWord] = useState('')
      const { uiState, setUiState } = useInstantSearch()
    
      const goToSearchPage = async () => {
        const indexName = process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME as string
    
        // 特定のページ(/search)などに移動させたい場合、先にリダイレクトさせる
        // await push(`/search?query=${word}`)
    
        setUiState({
          ...uiState,
          [indexName]: {
            ...uiState[indexName],
            query: word,
          },
        })
      }
    
      return (
            <form
              className='relative mt-1 flex rounded-md shadow-sm'
              onSubmit={(e) => {
                e.preventDefault()
                goToSearchPage()
              }}
            >
              <div className='relative flex items-stretch flex-grow focus-within:z-10'>
                <input
                  type='search'
                  name='search'
                  id='search'
                  className='focus:ring-indigo-500 focus:border-indigo-500 block w-full rounded-none rounded-l-md pl-5 sm:text-sm border-gray-300'
                  placeholder='Search'
                  onChange={({ target }) => setWord(target.value)}
                  value={word}
                />
              </div>
              <button
                type='submit'
                className='-ml-px relative inline-flex items-center space-x-2 px-4 py-2 border border-gray-300 text-sm font-medium rounded-r-md text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500'
              >
                <SearchIcon className='h-5 w-5 text-gray-400' aria-hidden='true' />
                <span className='hidden md:inline'>Search</span>
              </button>
            </form>
      )
    }
    

    これでこのような検索フォームが作成できます。

    inputタグのonChangeを使うことも可能

    上のサンプルでは、[Enter]キー入力または[検索ボタン]クリックで検索が走ります。

    入力があったらすぐに検索を走らせたい場合は、formonSubmitではなくinputonChangeを使うとよさそうです。

    <input
      onChange={({ target }) => {
        setUiState({
          ...uiState,
          [indexName]: {
            ...uiState[indexName],
            query: target.value,
          },
        })
      }}
    />

    この辺りは、AlgoliaへのAPIリクエスト数によって調整すればよいかなと思います。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark