You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 选项列表中显示勾选框,支持勾选多选
  2. 输入区域显示选中选项的总数,而非逐个展示标签

实现步骤

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:37:10