React-Select AsyncSelect多选:添加勾选框与显示选中数量
解决方案:react-select AsyncSelect实现带勾选框多选+显示选中总数
问题回顾
我有一个使用react-select AsyncSelect的简单React应用:
const handleInputChange = (value) => { setValue(value); }; const loadOptions = async (inputValue, callback) => { setTimeout(() => { callback([ { value: 'apple', label: 'Apple' }, { value: 'amazon', label: 'Amazon' }, { value: 'Microsoft', label: 'Microsoft' }, { value: 'Winter', label: 'Winter' }, { value: 'Autumn', label: 'Autumn' }, { value: 'Summer', label: 'Summer' }, ]); }, 1000); }; <div> <AsyncSelect isMulti name="select" isClearable loadOptions={loadOptions} cacheOptions defaultOptions /> </div>
需要实现两个需求:
- 选项列表中显示勾选框,支持勾选多选
- 输入区域显示选中选项的总数,而非逐个展示标签
实现步骤
1. 自定义带勾选框的选项组件
react-select没有内置勾选框,我们可以通过自定义Option组件实现:
const CustomOption = ({ data, isSelected, innerRef, innerProps }) => { return ( <div ref={innerRef} {...innerProps} style={{ display: 'flex', alignItems: 'center', padding: '8px' }}> <input type="checkbox" checked={isSelected} style={{ marginRight: '8px' }} onClick={(e) => e.stopPropagation()} /> <span>{data.label}</span> </div> ); };
isSelected用来同步选项的选中状态onClick={(e) => e.stopPropagation()}避免点击复选框时重复触发选项的选中事件
2. 自定义值容器,显示选中总数
替换默认的选中标签展示,自定义ValueContainer组件:
const CustomValueContainer = ({ children, selectProps }) => { const { value } = selectProps; const selectedCount = value?.length || 0; if (selectedCount > 0) { return ( <div style={{ display: 'flex', alignItems: 'center', padding: '8px', border: '1px solid #ccc', borderRadius: '4px', gap: '8px' }}> <span>已选 {selectedCount} 项</span> {children.slice(-1)} {/* 保留默认的清除按钮 */} </div> ); } return <>{children}</>; // 未选中时显示默认提示 };
3. 整合到AsyncSelect中
将自定义组件传入components属性,同时维护选中状态的state:
import { useState } from 'react'; import AsyncSelect from 'react-select/async'; export default function App() { const [selectedOptions, setSelectedOptions] = useState([]); const handleInputChange = (value) => { setSelectedOptions(value); }; const loadOptions = async (inputValue, callback) => { setTimeout(() => { callback([ { value: 'apple', label: 'Apple' }, { value: 'amazon', label: 'Amazon' }, { value: 'Microsoft', label: 'Microsoft' }, { value: 'Winter', label: 'Winter' }, { value: 'Autumn', label: 'Autumn' }, { value: 'Summer', label: 'Summer' }, ]); }, 1000); }; // 上面的CustomOption和CustomValueContainer组件放在这里 return ( <div style={{ width: 300, margin: '20px' }}> <AsyncSelect isMulti name="select" isClearable loadOptions={loadOptions} cacheOptions defaultOptions value={selectedOptions} onChange={handleInputChange} components={{ Option: CustomOption, ValueContainer: CustomValueContainer }} /> </div> ); }
效果说明
- 选项列表中的每个选项前会显示复选框,点击复选框或选项本身都能切换选中状态
- 当有选项选中时,输入框区域会显示
已选 X 项,同时保留清除按钮 - 未选中任何选项时,显示默认的输入提示
内容的提问来源于stack exchange,提问作者SVE
相关产品推荐
相关产品推荐

