如何使用React-Select创建可搜索的异步下拉菜单
介绍
HTML 提供了一个 <select>
元素,允许最终用户从 <option>
s 的下拉菜单中进行选择。 但是,在某些情况下,选择菜单可能会受益于额外的用户体验细节,例如允许用户过滤可用选项。
React Select 是一个高度可配置的 React 选择菜单库,具有动态搜索和过滤功能。 它还支持异步选项加载、可访问性和快速渲染时间。
在本教程中,您会将 React Select 添加到项目中。 您还将探索一些可用的附加功能:多选、用户可创建的选项和异步选项加载。
先决条件
要完成本教程,您需要:
- Node.js 的本地开发环境。 按照如何安装Node.js并创建本地开发环境来完成。
本教程已使用 Node v14.7.0、npm
v6.14.7、react
v16.13.1 和 react-select
v3.1.0 进行了验证。
第 1 步 — 设置项目
首先使用 create-react-app 生成 React App,然后安装依赖项:
npx create-react-app react-select-example
切换到新的项目目录:
cd react-select-example
现在,您可以运行 React 应用程序:
npm start
修复项目中的任何错误或问题,然后在网络浏览器中访问 localhost:3000
。
一旦你有一个工作的 React 应用程序,你就可以开始添加 React Select。
第 2 步 - 添加 React Select
您的项目将需要安装 react-select
库:
npm install react-select@3.1.0
注意: 目前,最新版本的库 (3.1.0) 存在问题,在使用 StrictMode
时,它会针对旧版和已弃用的 API 生成警告。 这些是 已知问题 ,一些待处理的拉取请求将解决其中的一些问题。
下面是修改 App.js
以显示水生动物下拉菜单的示例:
nano src/App.js
为 aquaticCreatures
添加一个数组,并使用 React Select 提供的 Select
组件:
src/App.js
import React from 'react'; import Select from 'react-select'; const aquaticCreatures = [ { label: 'Shark', value: 'Shark' }, { label: 'Dolphin', value: 'Dolphin' }, { label: 'Whale', value: 'Whale' }, { label: 'Octopus', value: 'Octopus' }, { label: 'Crab', value: 'Crab' }, { label: 'Lobster', value: 'Lobster' }, ]; function App() { return ( <div className="App"> <Select options={aquaticCreatures} /> </div> ); } export default App;
你会注意到三件事:
- 您必须从
react-select
导入Select
组件。 - 选项数组
aquaticCreatures
中的每个对象必须至少有两个值:label
,一个字符串,和value
,可以是任何类型。 - 唯一需要的道具是
options
数组。
注意: 如果你用字符串数组填充你的 React Select 组件,而不是手动重复 label
和 value
,你可以使用 JavaScript 的 map 数组方法 准备 options
数组:
someArrayOfStrings.map(opt => ({ label: opt, value: opt }));
要捕获用户选择选项的时间,请添加 onChange
属性:
src/App.js
<Select options={aquaticCreatures} onChange={opt => console.log(opt.label, opt.value)} />
传递给 onChange
函数的值与构成选项本身的对象相同,因此它将包含 label
和 value
变量。
运行你的项目:
npm start
然后,在您的网络浏览器中访问 localhost:3000
。
您将看到带有 aquaticCreatures
的 React Select 菜单:
如果您与此菜单交互,您将触发 onChange
事件并将消息记录到控制台。 通过打开浏览器的开发者控制台,您应该观察到您选择的 label
和 value
:
Output'Shark' 'Shark'
现在你有了一个可用的 React Select 菜单,你可以探索这个库提供的其他一些特性。
第 3 步 — 添加高级选项
除了搜索和选择之外,React Select 还提供了其他功能,例如多选、用户可创建的选项和异步选项加载。
多选
HTML <select>
支持 multiple
允许选择多个 <option>
。
同样,在 React Select 中,您可以通过将 isMulti
属性添加到您的元素来启用多选:
src/App.js
<Select options={aquaticCreatures} isMulti />
出于探索目的,还需要修改 onChange
属性以支持多选,因为 opt
不再是单个对象。 使用多选,它成为一个嵌套对象。 opt.label
和 opt.value
本来会返回 undefined
。
src/App.js
<Select options={aquaticCreatures} isMulti onChange={opt => console.log(opt)} />
运行你的项目:
npm start
然后,在您的网络浏览器中访问 localhost:3000
。
从 aquaticCreatures
中选择一个选项,然后选择另一个。 您的所有多项选择都应由组件指示:
多选功能到此结束。
用户可创建的选项
您可以提供 用户可创建选项 以允许用户在菜单中不存在他们想要的选项的情况下向选择菜单添加自定义值。
首先,您需要从 react-select/creatable
导入 Creatable
组件:
src/App.js
import Creatable from 'react-select/creatable';
然后,将 Select
组件替换为 Creatable
:
src/App.js
<Creatable options={aquaticCreatures} />
出于探索目的,还需要修改 onChange
属性以显示 meta
值:
src/App.js
<Creatable options={aquaticCreatures} onChange={(opt, meta) => console.log(opt, meta)} />
运行项目:
npm start
当您键入一个当前不存在的选项时(例如 Cuttlefish
),您将看到一个 'Create'
选项:
创建新菜单项后,您应该在浏览器的开发人员控制台输出中观察到以下内容:
Output{ label: 'Cuttlefish', value: 'Cuttlefish', __isNew__: true } { action: 'create-option' }
请注意,您有两种方法可以检测事件是否为新选项:所选选项的 __isNew__
变量和事件处理程序中 meta
参数的 action
值.
另外,请注意 label
和 value
将如何成为相同的字符串。 用户无法选择为 label
提供不同的 value
,这可能会影响您处理数据存储一致性解决方案的方式。
用户可创建的选项功能到此结束。
异步选项加载
您可以使用 异步选项加载 让用户在您的应用程序中体验更快的初始加载时间。 这只会在用户与之交互时填充组件。
与 Creatable
组件非常相似,您需要从 react-select/async
导入 AsyncSelect
:
import AsyncSelect from 'react-select/async'
然后,将 Select
组件替换为 Async
:
src/App.js
<AsyncSelect loadOptions={loadOptions} />
要加载选项,请将 loadOptions
属性传递给一个函数,类似于以下内容:
const loadOptions = (inputValue, callback) => { // perform a request const requestResults = ... callback(requestResults) }
React Select 还支持 [X31X] 属性,它在初始化时调用 loadOptions
函数来填充下拉列表,以及 cacheOptions
属性,它在其值为真时缓存选项。
异步选项加载功能到此结束。
结论
在本教程中,您将 React Select 添加到项目中。 React Select 的自定义和功能集有可能为您的用户提供比标准选择菜单更好的用户体验。
有关 props 和 高级功能 的更多信息可以在 React Select 文档中找到。
如果您想了解有关 React 的更多信息,请查看我们的 如何在 React.js 中编码,或查看 我们的 React 主题页面 以了解练习和编程项目。