react-autocomplete、react-autosuggest、react-select はいずれもReactアプリケーションでユーザー入力補完や選択機能を実現するためのライブラリです。react-autocomplete はシンプルなキーワードベースのサジェストを提供します。react-autosuggest は柔軟なサジェスト表示とカスタマイズ性に特化しています。一方、react-select は高度な選択機能(複数選択、検索付きドロップダウン、非同期ローディングなど)を備えた包括的なセレクトコンポーネントです。
Reactで入力補完や選択機能を実装する際、react-autocomplete、react-autosuggest、react-select の3つの主要な選択肢があります。それぞれ設計思想と用途が大きく異なるため、プロジェクトの要件に応じて適切に選ぶ必要があります。以下では、各ライブラリの技術的特性、実装例、および適用シナリオを詳しく比較します。
まず重要な点として、react-autocomplete は 公式に非推奨(deprecated) とされています。npmおよびGitHubのREADMEには明確にその旨が記載されており、新規プロジェクトでの使用は強く推奨されません。代わりに downshift や react-select などの代替手段を検討すべきです。
// react-autocomplete(非推奨)の基本的な使用例
import Autocomplete from 'react-autocomplete';
<Autocomplete
items={items}
getItemValue={(item) => item.label}
renderItem={(item, isHighlighted) => (
<div style={{ background: isHighlighted ? 'lightgray' : 'white' }}>
{item.label}
</div>
)}
value={value}
onChange={(e) => setValue(e.target.value)}
onSelect={(val) => setValue(val)}
/>
このライブラリはシンプルですが、アクセシビリティ対応やモダンなReactのライフサイクルへの対応が不十分であり、メンテナンスも停止されています。したがって、以下では主に react-autosuggest と react-select の比較に焦点を当てます。
react-autosuggest は、サジェストの表示ロジックとUIを完全に分離し、開発者が自由に制御できる設計です。入力値、サジェストリストの表示/非表示、フォーカス状態など、すべての状態を親コンポーネントで管理します。
// react-autosuggest の基本実装
import Autosuggest from 'react-autosuggest';
const getSuggestionValue = (suggestion) => suggestion.name;
const renderSuggestion = (suggestion) => <div>{suggestion.name}</div>;
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={({ value }) => {
setSuggestions(getSuggestions(value));
}}
onSuggestionsClearRequested={() => setSuggestions([])}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={{
placeholder: '国名を入力',
value,
onChange: (_, { newValue }) => setValue(newValue)
}}
/>
このアプローチの利点は、デザインシステムや特定のアクセシビリティ要件に完全に適合できる点です。ただし、選択後の状態管理(例:選択済みアイテムの保持)、複数選択、クリアボタンなどはすべて自前で実装する必要があります。
react-select は、選択コンポーネントとして必要な機能をほぼすべて内包しています。単一選択、複数選択、検索、非同期ローディング、グループ化、カスタムオプションレンダリングなどが標準でサポートされています。
// react-select の基本実装
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' }
];
<Select
options={options}
value={selectedOption}
onChange={setSelectedOption}
isSearchable
isMulti // 複数選択を有効化
/>
さらに、components プロパティを使えば、ドロップダウン内の各要素(オプション、インジケーター、プレースホルダーなど)を個別にカスタマイズできます。
// react-select のカスタムコンポーネント
const customComponents = {
Option: ({ children, ...props }) => (
<components.Option {...props}>
<span style={{ color: 'blue' }}>{children}</span>
</components.Option>
)
};
<Select components={customComponents} {...otherProps} />
react-autosuggest
// 入力に応じてサジェストをフィルタリング
const onSuggestionsFetchRequested = ({ value }) => {
const filtered = countries.filter(country =>
country.name.toLowerCase().includes(value.toLowerCase())
);
setSuggestions(filtered);
};
react-select
// react-select はデフォルトで検索機能を内蔵
// 追加実装不要
<Select options={countries} isSearchable />
react-autosuggest
複数選択は標準でサポートされておらず、以下のように自前で実装する必要があります。
// react-autosuggest で複数選択を実現するのは複雑
const [selectedItems, setSelectedItems] = useState([]);
const handleSelect = (suggestion) => {
setSelectedItems([...selectedItems, suggestion]);
setValue('');
setSuggestions([]);
};
// さらに、選択済みアイテムの表示・削除UIも別途実装が必要
react-select
// isMulti を指定するだけで複数選択可能
<Select
isMulti
options={options}
value={selectedOptions}
onChange={setSelectedOptions}
/>
react-autosuggest
// 非同期ローディングは手動で実装
const onSuggestionsFetchRequested = async ({ value }) => {
const results = await fetch(`/api/search?q=${value}`);
setSuggestions(results);
};
react-select
// AsyncSelect コンポーネントで簡単に実装
import AsyncSelect from 'react-select/async';
const loadOptions = (inputValue) =>
fetch(`/api/search?q=${inputValue}`).then(res => res.json());
<AsyncSelect loadOptions={loadOptions} />
react-autosuggest はARIA属性を適切に出力しますが、完全なアクセシビリティ対応には開発者の注意深い実装が必要です。一方、react-select はキーボードナビゲーション、スクリーンリーダー対応、フォーカス管理などを包括的に実装しており、追加の作業なしで高いアクセシビリティ基準を満たします。
| 要件 | 推奨ライブラリ |
|---|---|
| 新規プロジェクトで基本的なオートコンプリートが必要 | react-select(react-autocomplete は非推奨) |
| 完全にカスタムなサジェストUIとロジックが必要 | react-autosuggest |
| 複数選択、タグ入力、非同期ローディングなど高機能が必要 | react-select |
| デザインシステムに厳密に従う必要があり、UIの細部まで制御したい | react-autosuggest |
| 短期間で信頼性の高い選択コンポーネントを導入したい | react-select |
react-autocomplete は非推奨のため、新規プロジェクトでは使用しないでください。react-autosuggest は、UIや動作を完全にコントロールしたい上級者向けです。柔軟性が高い反面、実装コストも高くなります。react-select は、ほとんどのユースケースで「そのまま使える」完成度を持っており、開発速度と信頼性のバランスが非常に優れています。プロジェクトの要件が「標準的な検索付きドロップダウン」を超えない限り、react-select を第一候補にすることを強く推奨します。
react-select は、検索付きドロップダウン、複数選択、タグ入力、非同期データローディング、グループ化など、豊富な機能をすぐに使える形で提供します。多くのユースケースに対応でき、アクセシビリティも十分に考慮されています。標準的なUIで問題ない場合や、短期間で高機能な選択コンポーネントを実装したい場合に最適です。
react-autocomplete は軽量で基本的なオートコンプリート機能のみ必要な場合に向いています。ただし、npmおよびGitHubの公式ページによると、このパッケージは非推奨(deprecated)となっており、新規プロジェクトでの使用は避けるべきです。既存コードの保守以外では代替ライブラリを検討してください。
react-autosuggest は、完全にカスタマイズ可能なサジェストUIを必要とする開発者に適しています。サジェスト項目のレンダリング、入力値の制御、フォーカス管理などを細かく制御できるため、デザインシステムやアクセシビリティ要件が厳しいプロジェクトで有効です。ただし、選択後の状態管理や複数選択などの機能は自前で実装する必要があります。
The Select control for React. Initially built for use in KeystoneJS.
See react-select.com for live demos and comprehensive docs.
React Select is funded by Thinkmill and Atlassian. It represents a whole new approach to developing powerful React.js components that just work out of the box, while being extremely customisable.
For the story behind this component, watch Jed's talk at React Conf 2019 - building React Select
Features include:
The easiest way to use react-select is to install it from npm and build it into your app with Webpack.
yarn add react-select
Then use it in your app:
import React from 'react';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
class App extends React.Component {
state = {
selectedOption: null,
};
handleChange = (selectedOption) => {
this.setState({ selectedOption }, () =>
console.log(`Option selected:`, this.state.selectedOption)
);
};
render() {
const { selectedOption } = this.state;
return (
<Select
value={selectedOption}
onChange={this.handleChange}
options={options}
/>
);
}
}
import React, { useState } from 'react';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' },
];
export default function App() {
const [selectedOption, setSelectedOption] = useState(null);
return (
<div className="App">
<Select
defaultValue={selectedOption}
onChange={setSelectedOption}
options={options}
/>
</div>
);
}
Common props you may want to specify include:
autoFocus - focus the control when it mountsclassName - apply a className to the controlclassNamePrefix - apply classNames to inner elements with the given prefixisDisabled - disable the controlisMulti - allow the user to select multiple valuesisSearchable - allow the user to search for matching optionsname - generate an HTML input with this name, containing the current valueonChange - subscribe to change eventsoptions - specify the options the user can select fromplaceholder - change the text displayed when no option is selectednoOptionsMessage - ({ inputValue: string }) => string | null - Text to display when there are no optionsvalue - control the current valueSee the props documentation for complete documentation on the props react-select supports.
You can control the following props by providing values for them. If you don't, react-select will manage them for you.
value / onChange - specify the current value of the controlmenuIsOpen / onMenuOpen / onMenuClose - control whether the menu is openinputValue / onInputChange - control the value of the search input (changing this will update the available options)If you don't provide these props, you can set the initial value of the state they control:
defaultValue - set the initial value of the controldefaultMenuIsOpen - set the initial open value of the menudefaultInputValue - set the initial value of the search inputReact-select exposes two public methods:
focus() - focus the control programmaticallyblur() - blur the control programmaticallyCheck the docs for more information on:
The v5 release represents a rewrite from JavaScript to TypeScript. The types for v4 and earlier releases are available at @types. See the TypeScript guide for how to use the types starting with v5.
Thank you to everyone who has contributed to this project. It's been a wild ride.
If you like React Select, you should follow me on twitter!
Shout out to Joss Mackison, Charles Lee, Ben Conolly, Tom Walker, Nathan Bierema, Eric Bonow, Emma Hamilton, Dave Brotherstone, Brian Vaughn, and the Atlassian Design System team who along with many other contributors have made this possible ❤️
MIT Licensed. Copyright (c) Jed Watson 2022.