8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

react-autosuggest を React Hooks x TypeScript 上に入れてサジェスト機能を実装した

Last updated at Posted at 2020-10-14

react-autosuggestのGitHubに書かれてるサンプルコードはクラスコンポーネントですが、Hooks勢であれば関数型に書き直したいと思うもの。

英語でも情報がなかったようなのでTypeScript込みで書き直してみた

この記事の完成品

こんな感じで動くやつになる

reactAutosuggest.gif

【元ネタ】GtiHubのサンプルコード

元ネタはこれ。一番基本的な使い方
GitHub: https://github.com/moroshko/react-autosuggest#installation

sample.jsx
import Autosuggest from 'react-autosuggest';

const languages = [
  {
    name: 'C',
    year: 1972
  },
  {
    name: 'Elm',
    year: 2012
  },
  ...
];

const getSuggestions = value => {
  const inputValue = value.trim().toLowerCase();
  const inputLength = inputValue.length;

  return inputLength === 0 ? [] : languages.filter(lang =>
    lang.name.toLowerCase().slice(0, inputLength) === inputValue
  );
};

const getSuggestionValue = suggestion => suggestion.name;

const renderSuggestion = suggestion => (
  <div>
    {suggestion.name}
  </div>
);

class Example extends React.Component {
  constructor() {
    super();

    this.state = {
      value: '',
      suggestions: []
    };
  }

  onChange = (event, { newValue }) => {
    this.setState({
      value: newValue
    });
  };

  onSuggestionsFetchRequested = ({ value }) => {
    this.setState({
      suggestions: getSuggestions(value)
    });
  };

suggestions.
  onSuggestionsClearRequested = () => {
    this.setState({
      suggestions: []
    });
  };

  render() {
    const { value, suggestions } = this.state;

    const inputProps = {
      placeholder: 'Type a programming language',
      value,
      onChange: this.onChange
    };

    return (
      <Autosuggest
        suggestions={suggestions}
        onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
        onSuggestionsClearRequested={this.onSuggestionsClearRequested}
        getSuggestionValue={getSuggestionValue}
        renderSuggestion={renderSuggestion}
        inputProps={inputProps}
      />
    );
  }
}

関数がいろいろあってややこしいライブラリだが基本的に1つの関数名(及びstate)と1つのpropsが対応していると見るとわかりやすい(getSuggests関数とonChange関数は別)

sample.jsx
      <Autosuggest
        suggestions={suggestions} // suggestionsはサジェスト候補のオブジェクトが格納されたstate
        onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} // suggestionsの状態を更新する関数 
        onSuggestionsClearRequested={this.onSuggestionsClearRequested} // suggestionsを初期状態にする関数
        getSuggestionValue={getSuggestionValue} // langagesのオブジェクトからnameを取り出す関数
        renderSuggestion={renderSuggestion} // サジェスト一覧表示に使うJSXを返す
        inputProps={inputProps} // placeholder, value, onChange の初期値を渡す
      />

Hooks & TypeScript で置き換えた

型ファイルも一緒に落としておく

yarn add react-autosuggest @types/react-autosuggest

使うデータへLangTypeの型を宣言したり、useStateを使ったりクラスを関数に書き変えたりして置き換えた。

codesandbox: https://codesandbox.io/s/react-autosuggest-typescript-ptn91?fontsize=14&hidenavigation=1&theme=dark

ReactSuggest.tsx
import React, { BaseSyntheticEvent, FC, useState } from "react";
import Autosuggest from "react-autosuggest";

type LangType = {
  name: string;
  year: number;
};

const languages: LangType[] = [
  {
    name: "CCC",
    year: 1972
  },
  {
    name: "CyberMan",
    year: 1972
  },
  {
    name: "EtherNet",
    year: 2012
  },
  {
    name: "Entertainer",
    year: 10000
  }
];

const getSuggestions = (value: string): LangType[] => {
  const inputValue = value.trim().toLowerCase();
  const inputLength = inputValue.length;

  return inputLength === 0
    ? []
    : languages.filter(
        (lang) => lang.name.toLowerCase().slice(0, inputLength) === inputValue
      );
};

const ReactSuggestion: FC = () => {
  const [value, setValue] = useState("");
  const [suggestions, setSuggestions] = useState<LangType[]>([]);

  const getSuggestionValue = (suggestion: LangType): string => {
    const { name } = suggestion;

    return name;
  };

  const renderSuggestion = (suggestion: LangType) => {
    return <div>{suggestion.name}</div>;
  };

  const onChange = (
    event: BaseSyntheticEvent,
    { newValue }: { newValue: string }
  ) => {
    if (event) setValue(newValue);
  };

  const onSuggestionsFetchRequested = ({ value }: { value: string }) => {
    const suggestions: LangType[] = getSuggestions(value);
    setSuggestions(suggestions);
  };

  // Autosuggest will call this function every time you need to clear suggestions.
  const onSuggestionsClearRequested = () => {
    setSuggestions([]);
  };

  const inputProps = {
    placeholder: "cかeを入力してみて",
    value,
    onChange
  };

  return (
    <Autosuggest
      suggestions={suggestions}
      onSuggestionsFetchRequested={onSuggestionsFetchRequested}
      onSuggestionsClearRequested={onSuggestionsClearRequested}
      getSuggestionValue={getSuggestionValue}
      renderSuggestion={renderSuggestion}
      inputProps={inputProps}
    />
  );
};

export default ReactSuggestion;

まとめ

onChange関数の引数に使わないけれど event を入れておかないと怒られた。他にもオプションがあるのでGitHubリポジトリの方で確認してもらえればと思う。
GitHub: https://github.com/moroshko/react-autosuggest#installation

8
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?