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

如何使用@atlaskit/select实现级联异步选择器?

用@atlaskit/select实现级联异步选择器的解决方案

核心问题分析

你之前把城市选项数组cities直接赋值给第二个AsyncSelect的loadOptions,但@atlaskit的AsyncSelect要求loadOptions必须是返回Promise的函数,这就是数据能打印但渲染不出来的原因。

实现思路

  1. 国家选择器正常用异步函数加载选项,切换时触发城市数据的获取
  2. 城市选择器的loadOptions包装成返回Promise的函数,内部返回已缓存的城市数组
  3. 切换国家时清空城市的选中状态,避免旧数据残留
  4. 未选择国家时禁用城市选择器,提升体验

完整示例代码

import { useState } from 'react';
import { AsyncSelect } from '@atlaskit/select';

// 模拟获取国家列表的异步接口
const fetchCountries = async () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([
        { label: '中国', value: 'CN' },
        { label: '美国', value: 'US' },
        { label: '日本', value: 'JP' },
      ]);
    }, 500);
  });
};

// 模拟根据国家ID获取城市的异步接口
const fetchCitiesByCountry = async (countryId) => {
  const cityMap = {
    CN: [
      { label: '北京', value: 'CN-BJ' },
      { label: '上海', value: 'CN-SH' },
      { label: '广州', value: 'CN-GZ' },
    ],
    US: [
      { label: '纽约', value: 'US-NY' },
      { label: '洛杉矶', value: 'US-LA' },
      { label: '芝加哥', value: 'US-CH' },
    ],
    JP: [
      { label: '东京', value: 'JP-TK' },
      { label: '大阪', value: 'JP-OS' },
    ],
  };
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(cityMap[countryId] || []);
    }, 500);
  });
};

const CascadingSelect = () => {
  const [selectedCountry, setSelectedCountry] = useState(null);
  const [cities, setCities] = useState([]);
  const [selectedCity, setSelectedCity] = useState(null);

  // 切换国家时的处理逻辑
  const handleCountryChange = (option) => {
    setSelectedCountry(option);
    setSelectedCity(null); // 清空已选城市
    // 调用接口获取对应城市
    fetchCitiesByCountry(option.value).then(data => {
      setCities(data);
    });
  };

  // 城市选择器的loadOptions函数,必须返回Promise
  const loadCityOptions = async () => {
    return cities;
  };

  return (
    <div style={{ padding: '20px', maxWidth: '400px' }}>
      <div style={{ marginBottom: '16px' }}>
        <label style={{ display: 'block', marginBottom: '8px' }}>选择国家</label>
        <AsyncSelect
          loadOptions={fetchCountries}
          onChange={handleCountryChange}
          value={selectedCountry}
          placeholder="请选择国家"
          isClearable
        />
      </div>
      <div>
        <label style={{ display: 'block', marginBottom: '8px' }}>选择城市</label>
        <AsyncSelect
          loadOptions={loadCityOptions}
          onChange={(option) => setSelectedCity(option)}
          value={selectedCity}
          placeholder="请先选择国家"
          isDisabled={!selectedCountry}
          isClearable
        />
      </div>
    </div>
  );
};

export default CascadingSelect;

关键注意点

  • 城市选择器的loadOptions必须是异步函数,哪怕数据已经缓存好,也要返回Promise
  • 切换国家时一定要清空城市选中值,避免出现国家和城市不匹配的情况
  • 给城市选择器加isDisabled属性,未选国家时禁用,减少用户误操作

内容的提问来源于stack exchange,提问作者Fran b

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 21:53:15