🎉
react-autosuggest を React Hooks x TypeScript 上に入れてサジェスト機能を実装
react-autosuggestのGitHubに書かれてるサンプルコードはクラスコンポーネントですが、Hooks勢であれば関数型に書き直したいと思うもの。
英語でも情報がなかったようなのでTypeScript込みで書き直してみた
この記事の完成品
こんな感じで動くやつになる
【元ネタ】GtiHubのサンプルコード
元ネタはこれ。一番基本的な使い方
GitHub: https://github.com/moroshko/react-autosuggest#installation
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関数は別)
<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
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
Discussion